一行代码将两个命令放在同一行,来自多行输出 `find... | sort... | cut ...`

一行代码将两个命令放在同一行,来自多行输出 `find... | sort... | cut ...`

这是按紧跟在 SENT_ 后面的子字符串,递归地对文件名中含有字符串“SENT_”的文件进行排序,然后显示它们。Linux因为我认为最好把问题分开......

那里为我提供的帮助是给我一个命令(按秒数日期,即 $(date +%s) 作为文件中的子字符串),例如,

SENT_1593129066_edb8ff571bc493cb700c3ae6ccfa5869__HDR.tex_
SENT_1593129143_db550b5fa1578ba40c952dac10b9b779__HDR.tex_
SENT_1593129190_00d69a5407bb6f394609f1d387573e2e__HDR.tex_

我的目标是在同一行末尾用括号括住“正确日期”,即

SENT_1593129066_edb8ff571bc493cb700c3ae6ccfa5869__HDR.tex_ (June 20, 2020 15:32:33)
SENT_1593129143_db550b5fa1578ba40c952dac10b9b779__HDR.tex_ (July 21, 2020 19:44:02)
SENT_1593129190_00d69a5407bb6f394609f1d387573e2e__HDR.tex_ (Aug 22, 2020 04:43:38)

(日期和格式是虚构的)

所以我这么做是为了得到这个$(date +%s)角色,

gg () { find . -type f -name "*"$@"*" -printf '%f\n' |  sort -t'_' -k2.1,2.10 | cut -d'_' -f 2  ;  }
gg SENT

1593129066
1593129143
1593129190

cut是链接页面上唯一的新内容。

第一个问题曾是但幸运的是,date -d ???我发现: 如何通过管道将输出传输到 date -d “value”?

上面说date需要一个变量。所以我会尝试这个:

gg () { find . -type f -name "*"$@"*" -printf '%f\n' | \  
 sort -t'_' -k2.1,2.10 | \
 tee 
  >(echo "<FILENAME_LIKE_'SENT_1593130907_....tex'>" ) 
  >(cut -d'_' -f 2 | { read gmt ; date -d "$gmt"; } )  ; 
}

问题开始

我的想法是将两部分组合在一行上,即SENT_1593129066_edb8ff571bc493cb700c3ae6ccfa5869__HDR.tex_(第一部分 -还没有) 和(June 20, 2020 15:32:33)(第二部分) 通过使用tee管道将输出传输sort到两者;

  1. 打印/回显原始文件名,即第一部分,以及
  2. 括号中的日期,例如(June 20, 2020 15:32:33)

这个想法tee >(what_to_do) >(another_thing_to_do)来自于:

https://askubuntu.com/questions/833070/how-would-i-pass-the-output-of-one-command-to-multiple-commands

并且似乎将两个部分放在了同一条线上。如果不是,我想知道如果我需要将下面类似的东西包裹在tee... 中?但是现在它只执行>(echo...)一次“第一”部分...

把它们放在同一条线上的想法,是我考虑使用{ echo "The quick"; echo "brown fox"; } | tr "\n" " "

https://stackoverflow.com/questions/20871534/concatenate-in-bash-the-output-of-two-commands-without-newline-character?noredirect=1&lq=1


概括

所以我需要

  1. 执行 ' echo' 部分来恢复整个文件名(最好带有目录)和(date +%s)子字符串,例如~/dir_A/dir2/SENT_1593129066_asdfasdfasdf_asdf.tex,和
  2. 对于 找到的每个文件,将它们放在一行上find

这就是我想要的功能的结束。


编辑

这只起作用一次;(我不知道,paste但如果有更多常用工具会更好,但不是必要的......)

gg () { find . -type f -name "*"$@"*" -printf '%f\n' | \
 sort -t'_' -k2.1,2.10 | \
 paste  
  <(echo "<FILENAME_LIKE_'SENT_1593130907_....tex'>" ) 
  <(cut -d'_' -f 2 | { read gmt ; date -d @"$gmt"; } )  ; 
}

到目前为止修复它的尝试都失败了;

gg () { find . -type f -name "*"$@"*" -printf '%f\n' |  \
 sort -t'_' -k2.1,2.10 | \ 
 xargs -I'{}' paste  
  <(echo "<FILENAME_LIKE_'SENT_1593130907_....tex'>" ) 
  <(cut -d'_' -f 2 | { read gmt ; date -d @"$gmt"; } )  ; 
}

答案1

Bash 是一种编程语言(请阅读man bash),因此您可以执行循环。

例1:

find . -type f -name 'SENT*' -printf '%f\n' | \
   sort -t'_' -k2.1,2.10 | \
   ( 
     while read LINE ; 
     do 
       TS=$( echo "$LINE"| cut -d_ -f 2 ) ; 
       TSD=$( date  -d @$TS ) ;
       printf "%s (%s)\n"  "$LINE" "$TSD"  ;
     done
    )

示例 2(由另一位用户报告):

find . -type f -name 'SENT*' -printf '%f\n' | \
   sort -t'_' -k2.1,2.10 | \
   awk -F_ '{print $0" ("strftime("%c",$2)")"}'

相关内容