Bash Shell awk/xargs 魔法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8089882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 01:03:17  来源:igfitidea点击:

Bash Shell awk/xargs magic

bashawkxargs

提问by adbo

I'm trying to learn a little awk foo. I have a CSV where each line is of the format partial_file_name,file_path. My goal is to find the files (based on partial name) and move them to their respective new paths. I wanted to combine the forces of find,awk and mv to achieve this but I'm stuck implementing. I wanted to use awk to separate the terms from the csv file so that I could do something like
find . -name '*$1*' -print | xargs mv {} $2{}
where $1 and $2 are the split terms from the csv file. Anyone have any ideas?
-peace

我正在尝试学习一些 awk foo。我有一个 CSV,其中每一行的格式为 partial_file_name,file_path。我的目标是找到文件(基于部分名称)并将它们移动到各自的新路径。我想结合 find、awk 和 mv 的力量来实现这一点,但我一直在实施。我想使用 awk 将条款与 csv 文件分开,以便我可以做一些事情
find . -name '*$1*' -print | xargs mv {} $2{}
,其中 $1 和 $2 是来自 csv 文件的拆分条款。谁有想法?
-和平

回答by bos

I think you've got things mixed up here. {}can only be used in find, and only once. I.e you cannot do something like find -name '*.jpg' -exec mv {} {}.png.

我想你把事情搞混了。{}只能在 find 中使用,并且只能使用一次。即你不能做类似的事情find -name '*.jpg' -exec mv {} {}.png

Do this:

做这个:

$ cat korv
foo.txt,/hello/
bar.jpg,/mullo/
$ awk -F, '{print  " " }' korv
foo.txt /hello/
bar.jpg /mullo/

-F sets the delimiter, so the above will split using ",". Next, add * to the filenames:

-F 设置分隔符,因此上面的将使用“,”进行拆分。接下来,将 * 添加到文件名中:

$ awk -F, '{print "*""*" " " }' korv
*foo.txt* /hello/
*bar.jpg* /mullo/
**

This shows I have an empty line. We don't want this match, so we add a rule:

这表明我有一个空行。我们不想要这个匹配,所以我们添加一个规则:

$ awk -F, '/[a-z]/{print "*""*" " " }' korv
*foo.txt* /hello/
*bar.jpg* /mullo/

Looks good, so encapsulate all this to mv using a subshell:

看起来不错,所以使用子外壳将所有这些封装到 mv 中:

$ mv $(awk -F, '/[a-z]/{print "*""*" " " }' korv)
$

Done.

完毕。

回答by tripleee

You don't really need awk for this. There isn't really anything here which awk does better than the shell.

你真的不需要 awk 来实现这一点。这里真的没有什么比 shell 更好的 awk 了。

#!/bin/sh
IFS=,
while read file target; do
  find . -name "$file" -print0 | xargs -ir0 mv {} "$target"
done <path_to_csv_file

If you have special characters in the file names, you may need to tweak the read.

如果文件名中有特殊字符,则可能需要调整read.

回答by Shicheng Guo

find . -name "*err" -size "+10c" | awk -F.err '{print ".job"}' | xargs -I {} qsub {}

回答by aleph_null

what about using awk's system command:

使用awk的系统命令怎么样:

awk '{ system("find . -name "  " -print | xargs -I {} mv {} "  "{}"); }'

example arguments in the csv file: test.txt ./subdirectory/

csv 文件中的示例参数: test.txt ./subdirectory/