Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 使用“剪切”命令将空格用作分隔符_Bash_Unix_Cut - Fatal编程技术网

Bash 使用“剪切”命令将空格用作分隔符

Bash 使用“剪切”命令将空格用作分隔符,bash,unix,cut,Bash,Unix,Cut,我想在cut命令中使用空格作为分隔符 我可以使用什么语法 cut -d ' ' -f 2 其中2是所需空格分隔字段的字段号。您也可以说: cut -d\ -f 2 请注意,反斜杠后面有两个空格。,这是一个类似于cut的实用程序(我做的更智能但速度较慢),可以使用任何perl正则表达式作为中断标记。默认情况下,中断空白,但也可以中断多字符正则表达式、可选正则表达式等 scut -f='6 2 8 7' < input.file > output.file scut-f='6

我想在
cut
命令中使用空格作为分隔符

我可以使用什么语法

cut -d ' ' -f 2
其中2是所需空格分隔字段的字段号。

您也可以说:

cut -d\  -f 2
请注意,反斜杠后面有两个空格。

,这是一个类似于cut的实用程序(我做的更智能但速度较慢),可以使用任何perl正则表达式作为中断标记。默认情况下,中断空白,但也可以中断多字符正则表达式、可选正则表达式等

scut -f='6 2 8 7' < input.file  > output.file
scut-f='6 2 8 7'output.file

因此,上面的命令将打断空格上的列,并按该顺序提取(基于0的)cols 6 2 8 7

通常,如果使用空格作为分隔符,则需要将多个空格视为一个空格,因为要解析将某些列与空格对齐的命令的输出。(而谷歌对这一点的搜索让我走到了这里)

在这种情况下,单个
cut
命令是不够的,您需要使用:

tr -s ' ' | cut -d ' ' -f 2

我建议您也可以使用
“-d”

试验 补充现有的有用答案;感谢您鼓励我单独发布答案:

两种不同的机制在这里发挥作用:

  • (a)
    cut
    本身是否需要传递给
    -d
    选项的分隔符(在本例中为空格)作为单独的参数,或者是否可以将其直接附加到
    -d

  • (b) shell在将参数传递给被调用的命令之前通常是如何解析参数的

(a) 答案是引用了(矿山)的一句话

如果标准实用程序的概要显示带有强制选项参数的选项[…],则一致性应用程序应为该选项及其选项参数使用单独的参数然而,一致性实现还应允许应用程序在同一参数字符串中指定选项和选项参数,而不插入字符

换句话说:在这种情况下,因为
-d
的选项参数是必需的
您可以选择是否将分隔符指定为

  • (s) 任一:一个独立的参数
  • (d) 或者:作为值直接附加到
    -d
选择了(s)或(d)后,重要的是shell的字符串文本解析-(b):

  • 对于方法(s),以下所有形式都是等效的:

    • -d'
    • -d”“
    • -d\#出于技术原因,用于表示实际空间
  • 对于方法(d),以下所有形式都是等效的:

    • -d'
    • -d”“
    • “-d”
    • '-d'
    • d\
等价性由shell的字符串文字处理来解释:

上述所有解决方案在
cut
看到它们时会产生完全相同的字符串(每组):

  • (s)
    cut
    -d
    视为自己的参数,后跟一个单独的参数,该参数包含一个空格字符,不带引号或
    \
    前缀

  • (d)
    cut
    查看
    -d
    加空格字符-不带引号或
    \
    前缀作为同一论点的一部分

根据shell解析字符串文本的方式,各个组中的表单最终相同的原因有两个方面:

  • shell允许通过名为quoting的机制按原样指定文本,该机制可以采用多种形式:
    • 单引号字符串:
      “…”
      中的内容按字面理解并形成单个参数
    • 双引号字符串:
      “…”
      中的内容也构成一个参数,但要进行插值(扩展变量引用,如
      $var
      、命令替换(
      $(…)
      `.`
      ),或算术扩展(
      $(…)
    • \
      -引用单个字符
      :单个字符前面的
      \
      会将该字符解释为文字
  • 引号由补充,这意味着一旦shell解析了命令行,它就会从参数中删除引号字符(包括
    '…
    “…”
    \
    实例)-因此,被调用的命令永远看不到引号字符

如果数据有多个空格,则无法轻松使用cut。我发现规范化输入以便于处理很有用。一个技巧是使用sed进行规范化,如下所示

echo -e "foor\t \t bar" | sed 's:\s\+:\t:g' | cut -f2  #bar
我有一个答案(我承认答案有些混乱),涉及
sed
、正则表达式和捕获组:

  • \S*
    -第一个单词
  • \s*
    -分隔符
  • (\S*)
    -第二个单词-已捕获
  • *
    -行的其余部分
作为一个
sed
表达式,捕获组需要转义,即
\(
\)

\1
返回捕获组的副本,即第二个单词

$echo“alpha-beta-gamma-delta”sed's/\s*\s*\(\s*\)./\1/'
贝塔
当你看到这个答案时,你可能会觉得有点困惑,而且你可能会想,为什么要麻烦呢?好吧,我希望有些人可能会说“啊哈!”并使用这种模式来解决一些复杂的文本提取问题,只需一个
sed
表达式。

不正确,手册页
cut "-d "
$ cat a
hello how are you
I am fine
$ cut "-d " -f2 a
how
am
echo -e "foor\t \t bar" | sed 's:\s\+:\t:g' | cut -f2  #bar