这是一个简单的命令
file * | awk '/ASCII text/ {gsub(/:/,"",$1); print $1}' | xargs chmod -x
我无法理解上面显示的awk的用法。 它是如何工作的?
答案 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文本类型字符串中包含冒号。