Bash Shell awk/xargs magic

Bash Shell awk/xargs magic,bash,awk,xargs,Bash,Awk,Xargs,我想学一点阿福。我有一个CSV,其中每行的格式为部分文件名、文件路径。我的目标是找到文件(基于部分名称)并将它们移动到各自的新路径。我想结合find、awk和mv的力量来实现这一点,但我被困在了实施中。我想使用awk将术语从csv文件中分离出来,这样我就可以做类似于 find-名称'*$1*'-print | xargs mv{}$2{} 其中$1和$2是csv文件中的拆分条款。有人有什么想法吗?-peace使用awk的系统命令怎么样: awk '{ system("find . -name "

我想学一点阿福。我有一个CSV,其中每行的格式为部分文件名、文件路径。我的目标是找到文件(基于部分名称)并将它们移动到各自的新路径。我想结合find、awk和mv的力量来实现这一点,但我被困在了实施中。我想使用awk将术语从csv文件中分离出来,这样我就可以做类似于
find-名称'*$1*'-print | xargs mv{}$2{}


其中$1和$2是csv文件中的拆分条款。有人有什么想法吗?
-peace

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

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

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

我认为您在这里搞混了<代码>{}只能在“查找”中使用,并且只能使用一次。也就是说,您不能执行类似于
find-name'*.jpg'-execmv{}{}.png
的操作

这样做:

$ cat korv
foo.txt,/hello/
bar.jpg,/mullo/
$ awk -F, '{print $1 " " $2}' korv
foo.txt /hello/
bar.jpg /mullo/
-F设置分隔符,因此上面的内容将使用“,”进行拆分。接下来,将*添加到文件名中:

$ awk -F, '{print "*"$1"*" " " $2}' korv
*foo.txt* /hello/
*bar.jpg* /mullo/
**
这表明我有一个空行。我们不需要此匹配,因此添加了一条规则:

$ awk -F, '/[a-z]/{print "*"$1"*" " " $2}' korv
*foo.txt* /hello/
*bar.jpg* /mullo/
看起来不错,所以使用子shell将所有这些封装到mv:

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

完成。

你真的不需要awk。这里没有什么东西能比贝壳做得更好

#!/bin/sh
IFS=,
while read file target; do
  find . -name "$file" -print0 | xargs -ir0 mv {} "$target"
done <path_to_csv_file
#/垃圾箱/垃圾箱
如果=,
读取文件目标时;做
找到-名称“$file”-print0 | xargs-ir0 mv{}“$target”

好了,谢谢你的帮助。我不知道那个命令。那么完整的调用会是这样的:
awk'{system(“find.-name“$1”-print{xargs-I{}mv{}“$2{}”);}path_to_csv_文件
?最后一个“{}”是干什么的?至少对我来说,如果你把它去掉,效果会更好。@adbo:用-F运行它,对于csv文件。Bos的解决方案要好得多,假设您只想复制当前目录中的文件(在这种情况下,find变得完全不必要)。@tripleee:尽管它仍然适用于最后一个{},但您是对的,它没有必要。mv file.txt./subdir/file.txt与mv file.txt./subdir/的工作原理相同。回想起来,我会把它拿出来的。是的,我有点搞混了。很酷的sol'n和很好的解释。很多人都感谢你,xargs-i当然也支持{},但它一次只接受一个参数。
echo foo | xargs-n1 echo mv{}{}{}.txt
=>“mv{}{}.txt foo”对我来说。你忘了
-i
来自
xargs-i
。你可以多次使用
{/code>{/code>,例如
find-名称文件-exec mv{}{}.txt\是有效的。
find . -name "*err" -size "+10c" | awk -F.err '{print $1".job"}' | xargs -I {} qsub {}