for循环和带空格的文件

时间:2014-02-06 22:33:17

标签: linux bash

这是我的命令

for i in `find . -name '*Source*.dat'`; do cp "$i" $INBOUND/$RANDOM.dat; done;

以下是文件(只是一个示例):

/(12)SA1 (Admitting Diagnosis) --_TA1-1 + TA1-2/Source.dat
./(12)SA1 (Admitting Diagnosis) --_TA1-1 + TA1-2/Source_2000C.dat
./(13)SE1 (External Cause of Injury) --_ TE1-1+TE1-2/Source.dat
./(13)SE1 (External Cause of Injury) --_ TE1-1+TE1-2/Source_2000C.dat
./(13)SE1 (External Cause of Injury) --_ TE1-1+TE1-2/Source_POATest.dat
./(14)SP1(Primary)--_ TP1-1 + TP1-2/Source.dat
./(14)SP1(Primary)--_ TP1-1 + TP1-2/Source_2000C.dat
./(14)SP1(Primary)--_ TP1-1 + TP1-2/Source_ProcDateTest.dat
./(15)SP1(Primary)--_ TP1-1 + TP1-2 - SP2 -- TP2-1 + TP2-2/Source.dat
./(16)SP1(Primary)--_ TP1-1 + TP1-2 +TP1-3- SP2 -- TP2-1 + TP2-2/Source.dat
./(17)SP1(Primary)--_ TP1-1 + TP1-2 +TP1-3/Source.dat
./(18)SP1(Primary)--_ TP1-1 + TP1-2 - SP2 -- TP2-1 + TP2-2 - Copy/Source.dat
./(19)SD1 (Primary)+SD2 (Other Diagnosis)--_ TD12/Source.dat
./(19)SD1 (Primary)+SD2 (Other Diagnosis)--_ TD12/Source_2000C.dat
./(19)SD1 (Primary)+SD2 (Other Diagnosis)--_ TD12/Source_POATest.dat
./(2)SD3--_TD4 SD4--_TD4/Source.dat
./(2)SD3--_TD4 SD4--_TD4/Source2.dat

这些空格被bash标记化,但这不起作用。 另外,我想在这些文件的末尾添加一些随机性,这样它们就不会在目标目录中发生碰撞,但这是另一个故事。

5 个答案:

答案 0 :(得分:3)

find . -name '*Source*.dat' -exec sh -c 'cp "$1" "$2/$RANDOM.dat"' -- {} "$INBOUND" \;

使用-exec执行命令是空白安全的。使用sh执行cp对于为每个副本获取不同的$RANDOM是必要的。

答案 1 :(得分:1)

怎么样:

find . -name '*file*' -print0 | xargs -0 -I {} cp {} $INBOUND/{}-$RANDOM.dat

xargs是构造参数列表并将其传递给命令的便捷方式。

  • find -print0xargs -0一起使用,基本上是两个命令之间关于如何终止参数的协议。在这种情况下,它意味着空间不会被解释为参数的结尾。

  • -I {}{}设置为xargs的参数占位符。

至于随机化文件名以避免碰撞,显然有很多事情可以生成随机字符串来附加。但最重要的是,您确认新文件名不存在。您可以使用类似这样的循环来尝试:

$RANDOM=$(date | md5)
filename=$INBOUND/$RANDOM.dat
while [ -e $filename ]; do
  $RANDOM=$(date | md5)
  filename=$INBOUND/$RANDOM.dat
done

我不一定主张或反对使用当前时间的哈希生成随机文件名:主要的一点是,您希望首先检查该文件是否存在,以防万一。

答案 2 :(得分:1)

如果所有文件都在同一目录级别(如示例所示),则不需要find。例如,

 for i in */*Source*.dat; do
   cp "$i" $INBOUND/$RANDOM.dat
 done

将正确标记并找到正确的文件,前提是它们都位于当前目录的子目录中。

正如@chepner在评论中指出的那样,如果你有bash v4,你可以使用**

 for i in **/*Source*.dat; do
   cp "$i" $INBOUND/$RANDOM.dat
 done

应该找到与find完全相同的文件,而不会出现令牌化问题。

答案 3 :(得分:0)

有几种方法可以处理带空格的文件。您可以在管道中使用find,并阅读:

find . -name '*Source*.dat' | while read file ; do cp "$file" "$INBOUND/$RANDOM.dat"; done

答案 4 :(得分:0)

尝试类似

的内容
while read  i;do
  echo "file is $i"
  cp "$i" $INBOUND/$RANDOM.dat

done < <(find . -name '*Source*.dat')