根据文件内容移动文件

根据文件内容移动文件

目录全天都会收到大量文件。我只想根据第 2 行的内容选择并移动文件。第 2 行如下所示:

L054   EL621306DEM-A0-AGI378-0001  70807 201708072017081100061542364673600268
  • 条件 1:第 8 列和第 9 列 = EL
  • 条件 2:第 42/43/44/45 列 = 2017

ksh在 AIX 7.1 上使用)

答案1

使用 GNU 工具(GNU shell 或其他支持 ksh 的 shell)流程替代( <(...))、GNUxargs或类似 FreeBSD 的兼容 (for -a, -r, -0)、GNU mvfor -t、GNU awkfor nextfile(也受其他一些实现的支持;在不支持的情况下它将被忽略,但效率较低):

xargs -r0a <(
  find dir -type f -exec awk 'FNR == 2 {
    if (substr($0, 8, 2) == "EL" && substr($0, 42, 4) == "2017")
      printf "%s\0", FILENAME
    nextfile}' {} +)  echo mv -it /somewhere

echo(如果高兴就删除)

在非 GNU 系统上,您可以将其更改为:

{
find dir -type f -exec awk -v q="'" '
  function quote_for_xargs(s) {
    gsub(q, q "\\" q q, s)
    gsub("\n", q "\\\n" q, s)
    return q s q
  }
  FNR == 2 {
    if (substr($0, 8, 2) == "EL" && substr($0, 42, 4) == "2017")
      print quote_for_xargs(FILENAME)
    nextfile
  }' {} + | xargs sh -c '
  [ "$#" -eq 0 ] || exec echo mv -i "$@" /somewhere <&3 3<&-' sh
} 3<&0

(如果高兴就删除echo)。

也就是说,每个文本文件都有find调用。awk在 中awk,对于每个文件的第二行 ( FNR==2),如果满足条件,则打印文件名是适合的格式xargs(xargs 输入被视为由空格或换行符分隔的单词列表,其中单引号和双引号以及反斜杠可用于转义分隔符或彼此)。例如,一个名为 的文件./That's tough.log将输出为'./That'\''s tough.log'.

xargs接受该输入以将尽可能多的参数传递给sh.我们需要sh包装器,因为目标目录必须是最后一个参数。我们确实希望这样做,-i因为由于文件最终位于同一目录中,因此如果移动不同目录中具有相同名称的两个文件,则可能会丢失数据。我们确实需要mv的 stdin (用于-i提示)不是是来自 的管道find,因此使用临时 fd 3 将外部标准输入转发到shforsh来设置mv其上的标准输入。

相关内容