如何在命令行上接受文件列表并使用 xargs 创建所有文件的带日期的副本(basename_date.extension)?

如何在命令行上接受文件列表并使用 xargs 创建所有文件的带日期的副本(basename_date.extension)?

我花了很多时间来解决这个问题这里我已经成功地获得了正确的输出,而无需依靠 xargs 调用bash(本教程未涵盖)。花了一段时间才在子bash调用中正确引用xargs,由于某种原因,我必须将 保存replace-str在变量中,并重新计算date并将其保存在新变量中,因为:

编辑:我知道这rename也可以用来解决这个问题,但这在我链接的教程中尚未涵盖,也不是本练习的重点(如前所述,是使用 xargs)

  • 显然参数扩展不适用于replace-str= {} 所以我无法执行“{}%%.*”并获取文件扩展名
  • 显然,如果在命令中运行的子 bash 进程中使用,即使是双引号变量 也today将为 null xargs

    # %<conversions> come from 'man 3 strftime'                                                                                                                  
    today=$( date "+%Y-%m-%d" )

    # make prefix date copy                                                                                                                                      
    #ls "$@" | xargs -I ^ cp ^ "${today}_^"                                                                                                                        

    #make suffix date copy                                                                                                                                                                                                                                                       
    echo "$@" | sed "s; ;\n;g" | xargs -I {} \
                          bash -cs 'var="{}"; td=$( date "+%Y-%m-%d" ); \
                                    echo "${var%%.*}_${td}.${var##*.}"'
    #prints basename_.bash i.e. without date
    echo "$@" | sed "s; ;\n;g" | xargs -I {} \
                          bash -cs 'var="{}"; \
                                    echo "${var%%.*}_${today}.${var##*.}"'

将输出

    s1_2021-03-11.bash s2_2021-03-11.bash 

输入时

    ./myscript s1.bash s2.bash

编辑:重申输入看起来像

    ./myscript file1.ext file2.ext file3.ext ... fileN.ext

运行后ls应该存在如下文件

    file1_yyyy-mm-dd.ext ... fileN_yyyy-mm-dd.ext

如果可能的话,我宁愿找到一个不使用的解决方案,bash -c因为网站上的教程尚未涵盖这一点,所以我怀疑它的目的是解决问题。我还想了解我对参数扩展不能与 xargs 一起使用以及需要另一个日期变量的困惑。

答案1

如果我们无法访问 GNU 版本的 xargs/sed ,那么我们需要负责引用对 xargs 安全的文件名。

用法:

 ./myscript   your list of files goes here
#!/bin/bash

# user defined function: qXargs
# backslashes all chars special to xargs:
# SPC/TAB/NL/double quotes, single quotes, and backslash.

qXargs() {
  printf '%s\n' "$1" |
  sed \
    -e "s:[\\'${IFS%?}\"]:\\\\&:g" \
    -e '$!s:$:\\:'  \
  ;
}

# loop over command-line arguments
# quote them to make xargs safe and
# break apart arg into head portion and
#'extension and slip in today's date

today=$(date +'%Y-%d-%m')

for arg
do
   src=$(qXargs "$arg")
  head=$(qXargs "${arg%.*}")
  tail=$(qXargs "${arg##*.}")
  printf '%s\n%s_%s.%s\n'  \
    "$src" \
    "$head" "$today" "$tail" ;
done | xargs -n 2 -t mv -f --

假设实用程序是 GNU 版本。

#!/bin/bash
### this is the ./myscript file
d=$(date +'%Y-%d-%m')
printf '%s\0' "$@" |
sed -Ez "p;s/(.*)(\..*)/\1$d\2/" |
xargs -r0 -n2 -t mv -f --

笔记:

  • 您对无法从 xargs 替换字符串 {} 获取扩展名感到困惑的是 bcoz {} 只是一个占位符,提醒 xargs 将其替换为参数。因此 shell 在解析 xargs 命令时看不到它。

相关内容