命令行发现,sed的,EXEC [英] Commandline find, sed, exec

查看:485
本文介绍了命令行发现,sed的,EXEC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个文件夹中的一堆文件,子文件夹中,我试图让一些单行的快速复制/粘贴曾经在一段时间。

I have a bunch of files in a folder, in subfolders and I'm trying to make some kind of one-liner for quick copy/pasting once in a while.

内容是(太长,粘贴在这里): http://pastebin.com/4aZCPbwT

The contents is (too long to paste here): http://pastebin.com/4aZCPbwT

我试过下面的命令:

列出所有文件及其目录

找到。 -name'[!] *'

使用测试替换命名空间的所有实例:

Replace all instances of "Namespace" with "Test:

找到。 -name'* [!]'-print0 | SED的/命名空间/测试/ GI| xargs的-i -0回声{}

我需要做的是:

替换弗尔德斯的名称,如上述,并复制文件夹(包括文件),到另一个位置。创建文件夹,如果它们不存在(他们极有可能不会) - 不过,也有一些人​​说我不需要,喜欢./app,因为这个文件夹存在。我可以用-wholename'./app了点。

Replace foldes names like above, and copy the folders (including files), to another location. Create the folders if they don't exist (they most likely won't) - BUT, there are some of them that I don't need, like ./app, as this folder exists. I could use -wholename './app' for that.

当他们被复制,我需要更换的每个文件中一些文字,同上(命名空间测试 - 也occours里面的文件,并将它们保存当然)

When they are copied, I need to replace some text inside each file, same as above (Namespace with Test - also occours inside the files and save them of course).

这样的事情我会想象:

-print -exec的sed -i的/命名空间/测试/ GI'{} \\;

难道这三件事情可以在一班轮做了什么?替换文件中的文本(命名空间< =>测试),复制文件,包括他们与CP -p(不希望文件夹的写了)目录,但与上述重命名每个目录/文件(命名空间< =>测试)

Can these 3 things be done in a one-liner? Replace text in files (Namespace <=> Test), copy files including their directories with cp -p (don't want to write over folders), but renaming each directory/file with as above (Namespace <=> Test).

非常感谢: - )

推荐答案

除了描述的如何的苦心经营冗长下面,这种方法也可能是独一无二的,它结合了内置调试。它基本上没有做任何事情书面除了编译并保存到一个变量的所有命令,它认为它应该以执行要求的工作要做。

Besides describing the how with painstaking verbosity below, this method may also be unique in that it incorporates built-in debugging. It basically doesn't do anything at all as written except compile and save to a variable all commands it believes it should do in order to perform the work requested.

这也明确的避免循环尽可能。除了为的模式的多个匹配 SED 递归搜索的有没有其他的递归据我所知。

It also explicitly avoids loops as much as possible. Besides the sed recursive search for more than one match of the pattern there is no other recursion as far as I know.

而在去年,这完全是分隔 - 它不会对任何字符,除了。我不认为你应该有一个。

And last, this is entirely null delimited - it doesn't trip on any character in any filename except the null. I don't think you should have that.

顺便说一句,这是的真正的快。你看:

By the way, this is REALLY fast. Look:

% _mvnfind() { mv -n "${1}" "${2}" && cd "${2}"
> read -r SED <<SED
> :;s|${3}\(.*/[^/]*${5}\)|${4}\1|;t;:;s|\(${5}.*\)${3}|\1${4}|;t;s|^[0-9]*\(.*\)${5}|\1|p
> SED
> find . -name "*${3}*" -printf "%d\tmv %P ${5} %P\000" |
> sort -zg | sed -nz ${SED} | read -r ${6}
> echo <<EOF
> Prepared commands saved in variable: ${6}
> To view do: printf ${6} | tr "\000" "\n"
> To run do: sh <<EORUN
> $(printf ${6} | tr "\000" "\n")
> EORUN
> EOF
> }
% rm -rf "${UNNECESSARY:=/any/dirs/you/dont/want/moved}"
% time ( _mvnfind ${SRC=./test_tree} ${TGT=./mv_tree} \
> ${OLD=google} ${NEW=replacement_word} ${sed_sep=SsEeDd} \
> ${sh_io:=sh_io} ; printf %b\\000 "${sh_io}" | tr "\000" "\n" \
> | wc - ; echo ${sh_io} | tr "\000" "\n" |  tail -n 2 )

   <actual process time used:>
    0.06s user 0.03s system 106% cpu 0.090 total

   <output from wc:>

    Lines  Words  Bytes
    115     362   20691 -

    <output from tail:>

    mv .config/replacement_word-chrome-beta/Default/.../googlestars \
    .config/replacement_word-chrome-beta/Default/.../replacement_wordstars        

注意:的上述函数可能会要求 GNU 版本 SED 找到来妥善处理找到的printf SED -z -e :;递归正则表达式测试;吨来电。如果这些都没有提供给你的功能可以有可能与一些小的调整被复制。

NOTE: The above function will likely require GNU versions of sed and find to properly handle the find printf and sed -z -e and :;recursive regex test;t calls. If these are not available to you the functionality can likely be duplicated with a few minor adjustments.

您从开始想这应该尽一切努力用很少大惊小怪完成。我做了 SED ,但我也练了一些 SED 递归分支技术,所以这就是为什么我在这里。这有点像在学校理发得到一个打折理发,我猜。这里的工作流程:

This should do everything you wanted from start to finish with very little fuss. I did fork with sed, but I was also practicing some sed recursive branching techniques so that's why I'm here. It's kind of like getting a discount haircut at a barber school, I guess. Here's the workflow:


  • 室射频$ {UNNECESSARY}

    • 我故意留出可能删除或销毁任何类型的数据的功能调用。你提到 ./应用可能是不必要的。删除或其他事前移动它,或者,你可以建立一个 \\(-path PATTERN -exec室射频\\ {\\} \\)例程找到来做到这一点编程,但一个人的都是你的。

    • rm -rf ${UNNECESSARY}
      • I intentionally left out any functional call that might delete or destroy data of any kind. You mention that ./app might be unwanted. Delete it or move it elsewhere beforehand, or, alternatively, you could build in a \( -path PATTERN -exec rm -rf \{\} \) routine to find to do it programmatically, but that one's all yours.

      • 声明参数和调用函数的工人。 $ {sh_io} 是因为它节省了从函数返回尤其重要。 $ {sed_sep} 进来紧随其后;这是用来引用的sed 的递归函数中的任意字符串。如果 $ {sed_sep} 设置为可能在你的任何路径依赖或文件名中找到采取行动......嗯,就是不让一个值它可以。

      • Declare its arguments and call the worker function. ${sh_io} is especially important in that it saves the return from the function. ${sed_sep} comes in a close second; this is an arbitrary string used to reference sed's recursion in the function. If ${sed_sep} is set to a value that could potentially be found in any of your path- or file-names acted upon... well, just don't let it be.

      • 整个树从开始移动。这将节省大量的头痛;相信我。你想做什么其余的 - 重命名 - 仅仅是文件系统元数据的问题。如果你是,例如,从一个驱动器移动本到另一个,或通过任何类型的文件系统边界,你最好使用一个命令这样做一次。它也更安全。注意 MV -noclobber 选项设置;书面,此功能将不会把 $ {SRC_DIR} $ {TGT_DIR} 已存在。

      • The whole tree is moved from the beginning. It will save a lot of headache; believe me. The rest of what you want to do - the renaming - is simply a matter of filesystem metadata. If you were, for instance, moving this from one drive to another, or across filesystem boundaries of any kind, you're better off doing so at once with one command. It's also safer. Note the -noclobber option set for mv; as written, this function will not put ${SRC_DIR} where a ${TGT_DIR} already exists.

      • 我所在这里所有的命令sed的年代,以节省逃避麻烦和他们读入一个变量来养活下面的sed。下面说明。


      • 我们开始找到过程。随着找到我们只搜索任何需要重命名,因为我们已经做了所有的地方到地方的MV 操作与函数的第一个命令。而不是采取与的任何直接的行动找到,像 EXEC 调用,比如,我们用它代替打造出来的命令行动态与 -printf

      • We begin the find process. With find we search only for anything that needs renaming because we already did all of the place-to-place mv operations with the function's first command. Rather than take any direct action with find, like an exec call, for instance, we instead use it to build out the command-line dynamically with -printf.

      • 找到查找文件,我们需要它直接生成并打印出(的的),我们需要处理的重命名命令。在 DIR%深度上涨到每行的开头将有助于确保我们不会试图在树中的一个文件或目录重命名,目前尚未父对象要重命名。 找到使用各种优化技术,走你的文件系统树,它不是一个肯定的事,它会返回我们需要一个安全的换操作顺序数据。这就是为什么我们下一个...

      • After find locates the files we need it directly builds and prints out (most) of the command we'll need to process your renaming. The %dir-depth tacked onto the beginning of each line will help to ensure we're not trying to rename a file or directory in the tree with a parent object that has yet to be renamed. find uses all sorts of optimization techniques to walk your filesystem tree and it is not a sure thing that it will return the data we need in a safe-for-operations order. This is why we next...

      • 我们排序所有的发现的基础上%目录深入输出 所以,在关系最近的路径为$ {} SRC首先的工作。这样就避免了可能涉及的错误 MV ING文件到不存在的位置,并且它最大限度地减少需要递归循环。 (事实上,你可能会pssed找到所有的循环硬$ P $ 的)

      • We sort all of find's output based on %directory-depth so that the paths nearest in relationship to ${SRC} are worked first. This avoids possible errors involving mving files into non-existent locations, and it minimizes need to for recursive looping. (in fact, you might be hard-pressed to find a loop at all)

      • 我觉得这是整个脚本的唯一循环,它只是循环的第二个%路径在打印的情况下,它包含多个$ {每串OLD}值,可能需要更换。所有其他解决方案我想象中涉及到第二个 SED 过程,虽然很短的循环可能不是理想的,当然它打败产卵和分叉的整个过程。

      • 所以基本上 SED 在这里所做的就是搜索$ {sed_sep},然后,在找到它,直到它找到$保存它,当它遇到的所有字符{OLD} ,它再与$ {NEW}取代。然后,头回到$ {} sed_sep,再次寻找$ {OLD},如果它发生比字符串中出现多次。如果没有找到它,它打印修改后的字符串标准输出(它捉住,然后再下一个),并结束循环。

      • 这样就不必解析整个字符串,并确保 MV 命令字符串,这需要包括$上半年{OLD}当然也包括它,下半场被改变多次,有必要从 MV 的目标路径擦拭$ {OLD}名称。

      • I think this is the only loop in the whole script, and it only loops over the second %Path printed for each string in case it contains more than one ${OLD} value that might need replacing. All other solutions I imagined involved a second sed process, and while a short loop may not be desirable, certainly it beats spawning and forking an entire process.
      • So basically what sed does here is search for ${sed_sep}, then, having found it, saves it and all characters it encounters until it finds ${OLD}, which it then replaces with ${NEW}. It then heads back to ${sed_sep} and looks again for ${OLD}, in case it occurs more than once in the string. If it is not found, it prints the modified string to stdout (which it then catches again next) and ends the loop.
      • This avoids having to parse the entire string, and ensures that the first half of the mv command string, which needs to include ${OLD} of course, does include it, and the second half is altered as many times as is necessary to wipe the ${OLD} name from mv's destination path.

      • 的两个 -exec 通话发生在这里没有第二个。首先,正如我们所看到的,我们修改 MV 提供的命令找到的 -printf 函数命令正确改变的$ {OLD}至$ {NEW}所有引用,但为了做到这一点,我们不得不使用这不应该是一些任意的参考点包含在最终的输出。所以一旦 SED 完成所有需要做的,我们指示它从保持缓冲一起传递之前,消除其参考点。

      • The two -exec calls here happen without a second fork. In the first, as we've seen, we modify the mv command as supplied by find's -printf function command as necessary to properly alter all references of ${OLD} to ${NEW}, but in order to do so we had to use some arbitrary reference points which should not be included in the final output. So once sed finishes all it needs to do, we instruct it to wipe out its reference points from the hold-buffer before passing it along.

      ,现在我们回到我的身边

      AND NOW WE'RE BACK AROUND

      将收到类似如下的命令:

      read will receive a command that looks like this:

      % mv /path2/$SRC/$OLD_DIR/$OLD_FILE /same/path_w/$NEW_DIR/$NEW_FILE \000
      

      它将 $ {味精} $ {sh_io} 可随意功能之外进行检查。

      It will read it into ${msg} as ${sh_io} which can be examined at will outside of the function.

      酷。

      -Mike

      这篇关于命令行发现,sed的,EXEC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆