awk脚本从文件类型中删除ASCII

时间:2011-03-18 07:31:49

标签: regex scripting sed awk

这是一个简单的命令

file * | awk '/ASCII text/ {gsub(/:/,"",$1); print $1}' | xargs chmod -x

我无法理解上面显示的awk的用法。 它是如何工作的?

3 个答案:

答案 0 :(得分:1)

有一个删除的答案非常接近于避免文件名中的空格或冒号以及file的输出问题。我已经投票取消删除答案,但我会继续发布一些改进并添加一些解释。

file -0 * | awk -F '\0' '$2 ~ /ASCII text/ {print $1 "\0"}' | xargs -0 chmod -x

由于文件名中不允许使用空值,因此将它们用作分隔符是安全的。此管道中的每个步骤都使用空值。 file输出它们,awk在输入中接受它们并输出它们,xargs在输入中接受它们。我还将匹配特定于描述字段,因此它不会在文件的异常情况下触发误报,该文件的名称类似于“ASCII文本”,但实际上其内容不是。

正如其他人所说,你发布的AWK命令匹配来自file命令的输出行,其中包含行中某处的“ASCII文本”。然后从字段1删除每个冒号(因为gsub()是全局替换),这是冒号空格分隔的文件名。如果文件名包含冒号或空格(或两者或多个),则会出现潜在问题。文件名将被截断,chmod将失败,甚至可能在名称相似的文件上被错误触发(例如“foo bar”和“foo”都存在,“foo”不是ASCII文本文件,所以你不希望它被触及,但“foo bar”被截断为“foo”和oops!)。空间是潜在问题的原因是默认情况下,AWK会在空格和制表符上进行字段分割。

您发布的管道的AWK部分细分:

  • /ASCII text/ { - 对于与正则表达式匹配的每一行
  • gsub(/:/,"",$1); - 对于第一个字段中的每个冒号(作为正则表达式),替换空字符串
  • print $1} - 打印如此修改的第一个字段

答案 1 :(得分:0)

我在猜测,但看起来它正在提取文件命令输出中:之前的部分(即文件名)。 gsub部分将删除文件名中的:,因此foo.txt: ASCII text之类的内容将变为foo.txt ASCII text。然后,打印将打印空格分隔列表中的第一个项目(在本例中为文件名foo.txt)。所有这些文件都将被chmod无法执行。

这看起来很乏味。在grepping之后简单地说awk -F: '{print $1}'而不是整个替换技巧可能更容易。此外,如果文件名中包含空格,则会中断。

答案 2 :(得分:0)

使用file确定每个文件的类型(内容),然后选择ASCII文本的那些文件,并从第一个冒号中删除所有内容(假设它是文件名和文件类型之间的分隔符) ;当文件名中包含冒号时,这很脆弱;正如Noufel指出的那样,它也是这样做的,然后使用xargs批处理然后清除执行位。 (这样做的通常原因是从Windows传输的文件,它没有执行位,因此所有文件最终都会设置为Unix所见的执行位。)

空间破损是可以解决的; xargs了解引文。我会打破 last 冒号而不是第一个冒号,因为file通常不会在其ASCII文本类型字符串中包含冒号。