我有一个这样的文本文件:
Order,Site_ID
[email protected],AR-Slu
“订单”列包含我想要移动到“Site_ID”列中显示的相应文件夹(文本文件中的同一行)的文件夹的名称。这是仅移动一个文件夹的示例。在此示例中,我想移动文件夹'[电子邮件受保护]' 到文件夹'AR-Slu'。表中包含的信息是文件夹的名称,但没有文件夹的路径信息。但是,这两个文件夹位于同一父文件夹中。有人知道该怎么做吗?
答案1
对于空白分隔值
(如您问题的最初版本)
(cd /parent/folder && tail -n +2 | xargs -L 1 mv --) < file
这tail
是跳过标题。
使用 时-L 1
,每 1 行输入xargs
运行一个命令mv
字该行作为参数传递给mv
.
为了xargs
,字都是空白分隔的(是全是空格还是只有空格和制表符取决于实现xargs
),但xargs
也识别"
,'
和\
作为可用于转义这些空格或彼此之间的引用运算符。
您还可以使用while read
shell 循环:
(
cd /parent/folder || exit
unset -v IFS
read skip_header <&3
ret=0
while read src dst rest_ignored <&3; do
mv -- "$src" "$dst" || ret=$?
done
exit "$ret"
) 3< file
同样,对于read
和 使用默认值$IFS
(或之后unset IFS
),单词以空格或制表符分隔。\
可用于转义这些行或本身或在下一个物理行上继续行。
对于 CSV 文件
如果文件是 CSV 文件(值由引号分隔,
并可能被引号包围),那么您可以在ksh93
shell 中运行该循环并使用-S
其read
内置选项进行 CSV 解析:
#! /bin/ksh93 -
(
cd /parent/folder || exit
IFS=,
read -S skip_header <&3
ret=0
while read -S src dst rest_ignored <&3; do
mv -- "$src" "$dst" || ret=$?
done
exit "$ret"
) 3< file
您可以取消该-S
选项,这样它也可以在其他 POSIX shell 中工作,bash
只要文件中未使用 CSV 引用就可以工作。
或者您可以使用 CSV 解析模块perl
或其他脚本语言:
(cd /parent/folder && perl -C -MText::CSV -e '
$c = Text::CSV->new;
$ret = 0;
$c->getline(STDIN); # skip header
while (($src, $dst) = @{$c->getline(STDIN)}) {
system "mv", "--", $src, $dst;
$ret = 1 if $?;
}
exit $ret;') < file