我创建了一个文本文件,其中包含文件名列表,如下所示
022694-39.tar
022694-39.tar.2017-05-30_13:56:33.OLD
022694-39.tar.2017-07-04_09:22:04.OLD
022739-06.tar
022867-28.tar
022867-28.tar.2018-07-18_11:59:19.OLD
022932-33.tar
我试图逐行读取文件,然后使用awk在 .tar 之后删除任何内容,并使用它来创建文件夹(除非存在)。
然后计划将原始文件复制到具有$ LINE中存储的原始全名的新文件夹中。
$QNAP= "Path to storage"
$LOG_DIR/$NOVA_TAR_LIST= "Path to text file containing file names"
while read -r LINE; do
CURNT_JOB_STRIPED="$LINE | `awk -F ".tar" '{print $1}'`"
if [ ! -d "$QNAP/$CURNT_JOB_STRIPED" ]
then
echo "Folder $QNAP/$CURNT_JOB_STRIPED doesn't exist."
#mkdir "$QNAP/$CURNT_JOB_STRIPED"
fi
done <"$LOG_DIR/$NOVA_TAR_LIST"
不幸的是,这似乎是在尝试创建目录时尝试将所有文件名连接在一起,而不是一个一个地做,而我得到一个
File name too long
输出:
......951267-21\n951267-21\n961075-07\n961148-13\n961520-20\n971333-21\n981325-22\n981325-22\n981743-40\n999111-99\n999999-04g\n999999-44': File name too long
很抱歉,这很简单,有点菜鸟...
答案 0 :(得分:1)
尝试如下修改脚本:
CURNT_JOB_STRIPED=$(echo "${LINE}" | awk -F ".tar" '{print $1}')
您必须使用$(...)
进行命令替换。另外,应该打印变量LINE
,以防止外壳程序将其值解释为命令,而是将其传递给管道的下一个命令(作为输入)。最后,您应该从awk
表达式中删除反引号(这是命令替换的不建议使用的语法),因为您想要的是管道命令的结果。
有关更多信息,请查看http://tldp.org/LDP/abs/html/commandsub.html
或者,可读性差得多(两者都没有更高的性能,因此也只是出于“好奇心”),您可以使用而不是整个while循环:
xargs -I{} bash -c 'mkdir -p "${2}/${1%.tar*}"' - '{}' "${QNAP}" < "${LOG_DIR}/${NOVA_TAR_LIST}"
答案 1 :(得分:1)
问题出在CURNT_JOB_STRIPED="$LINE | `awk -F ".tar" '{print $1}'`"
行。
`command`
是旧式语法,应改为使用$(command)
。
$LINE
变量应打印出来,以便awk可以通过管道接收其值。
如果您在子外壳程序($(command)
中运行整个程序,则可以将输出分配给变量:var=$(date)
将变量放入${}
是比较安全的,因此,如果周围有文本,则不会得到意外的结果。
这应该起作用:
CURNT_JOB_STRIPED=$(echo "${LINE}" | awk -F '.tar' '{print $1}')
使用变量替换可以通过更高效的代码来实现,而且我相信阅读起来也很干净。
变量替换不会更改${LINE}
变量,因此以后可以将其用作具有完整文件名的变量,而${LINE%.tar*}
从变量值中剪切最后一个.tar
文本,然后然后*
开始。
while read -r LINE; do
if [ ! -d "${QNAP}/${LINE%.tar*}" ]
then
echo "Folder ${QNAP}/${LINE%.tar*} doesn't exist."
#mkdir "${QNAP}/${LINE%.tar*}"
fi
done <"${LOG_DIR}/${NOVA_TAR_LIST}"
这样,您就不会将目录名存储为变量,而${LINE}
仅存储文件名。如果您需要将其放入变量中,则可以轻松完成此操作:var="${LINE%.tar*}"
变量替换:
还有更多我只选择了这4个,因为它们在这里相似且相关。
$ {var#pattern}-从左侧删除与模式匹配的文本后使用var的值
$ {var ## pattern}-与上面相同,但是删除了最长的匹配项,而不是最短的
$ {var%pattern}-从右侧删除匹配模式的文本后使用var的值
$ {var %% pattern}-与上面相同,但删除了最长的匹配项而不是最短的