1

这真的不言自明。我在 bash shell 中工作,我对 shell 脚本很陌生。我找到了很多关于使用的信息trsed但是到目前为止我发现的所有示例都删除了分隔符和新行。我真的想做相反的事情。我希望能够根据空白进行分离。我有一个像“abcd efgh”这样的字符串,我需要它是“abcd”“efgh”(全部不带引号,只是为了显示分组)。

我敢肯定这比我做的要简单得多,但我很困惑。

更新的问题:

我有一列已放入数组的 PID,但数组的每个元素都有列中的 pid。

柱子:

1234
5678

当我打印出整个数组时,所有不同的列都已添加,因此我拥有所有值,但是当我打印出数组的单个元素时,我得到如下信息:

1234 5678

这不是我想要的。我需要一个用于 1234 的元素和一个用于 5678 的单独元素。

到目前为止,这是我的代码:

!/bin/bash
echo "Enter the File Name"
read ips

index=0
IFS=' '
while read myaddr myname; do
    myips[$index]="$myaddr"
    names[$index]="$myname"
    index=$(($index+1))
done < $ips

echo "my IPs are: ${myips[*]}"
echo "the corresponding names are: ${names[*]}"
echo "Total IPs in the file: ${index}"

ind=0
for i in "$myips[@]}"
do
    echo $i
    pids=( $(jps | awk '{print $1}') )

    for pid in "${pids[@]}"; do
        echo $pid
    done

    echo "my PIDs are: ${pids}"

    for j in "${pids[@]}"
    do
        mypids[$ind]="$j"
        ind=$(($ind+1))
    done
done
echo "${mypids[*]}"
echo "The 3rd PID is: ${mypids[2]}"

样品输出:

Total IPs in the file: 6

xxx.xxx.xxx.xxx
5504
1268
1
xxx.xxx.xxx.xxx
5504
4352
1

xxx.xxx.xxx.xxx
5504
4340
1

5504
1268 5504
4352 5504
4340

The 3rd pid is: 5504
4340

我需要将每个 pid 分开,以便数组的每个元素都是一个 pid。因此,例如,“The 3rd pid is:”行需要看起来像

The 3rd pid is: 5504

第 4 个元素是 4340

4

6 回答 6

3

尝试cut

$ echo "abcd efgh" | cut -d" " -f1
abcd

$ echo "abcd efgh" | cut -d" " -f2
efgh

或者,如果在某些时候您想做更复杂的事情,也请查看awk

$ echo "abcd efgh" | awk '{print $1}'
abcd

$ echo "abcd efgh" | awk '{print $2}'
efgh

要解决您更新的问题:

我有一列已放入数组的 PID,但数组的每个元素都有列中的 pid。

如果要将一列数据加载到数组中,可以执行以下操作:

$ pgrep sshd  # example command. Get pid of all sshd processes
795
32046
32225

$ A=(`pgrep sshd`) # store output of command in array A

$ echo ${A[0]}  # print first value
795

$ echo ${A[1]}  # print second value
32046

为了解决您发布的示例代码,问题的原因是您已更改$IFS为空格 ( IFS=' '),这意味着您的由换行符分隔的列不再被拆分。

考虑这个例子:

$ A=(`pgrep sshd`)
$ echo ${A[0]}  # works as expected
795

$ IFS=' '       # change IFS to space only
$ A=(`pgrep sshd`)  
$ echo ${A[0]}  # newlines no longer used as separator
795
32046
32225

为避免此问题,一种常见的方法是始终备份原始IFS数据,并在使用更新后的值后将其替换。例如

# backup original IFS
OLDIFS=$IFS

IFS=' '
# .. do stuff ...

# restore after use
IFS=$OLDIFS
于 2012-08-03T16:29:34.103 回答
1

示例文件:

abcd efgh
bla blue

使用 awk 您可以执行以下操作

cat file.txt | awk '{print $1}'

这将输出以下内容

abcd
bla

或者

cat file.txt | awk '{print $2}'

这将输出以下内容

efgh
blue

awk 是一个非常强大的命令,我建议您尽快尝试学习它。它将在 bash 脚本中为您省去很多麻烦。

于 2012-08-03T16:30:11.530 回答
1

其他解决方案都很好。我经常使用cut。但是,我只想补充一点,如果您总是想在空格上拆分,那么 xargs 会为您执行此操作。然后 printf 的命令行版本可以格式化参数(如果需要重新排序字符串,请使用 awk ,就像在其他解决方案中一样)。这是一个供参考的示例:

MYSTR="hello big world"
$ echo $MYSTR |xargs printf "%s : %s >  %s\n"
hello : big >  world
于 2012-08-03T16:42:59.820 回答
0

read命令将输入​​作为整行处理(除非使用 设置分隔符-e):

$ echo "abcd efgh" | while read item
do
    echo $item
    # Do something with item
done

abcd efgh

如果要将每个项目通过管道传输到命令,可以执行以下操作:

echo "abcd efgh" | tr ' ' '\n' | while read item
do
    echo $item
    # Do something with item
done

abcd
efgh
于 2012-08-03T16:56:49.283 回答
0

无需使用外部命令将字符串拆分为单词。set内置就是这样做的:

string="abcd efgh"
set $string

# Now $1 is "abcd" and $2 is "efgh"
echo $1
echo $2
于 2012-08-03T20:36:28.853 回答
-1

"abcd efgh"字符串和字符串之间没有区别,"abcd" "efgh"除了,如果作为参数传递给程序,第一个将作为一个参数读取,而第二个将是两个参数。

双引号"仅激活和停用 shell 扩展,就像单引号一样(但更激进)。

'"abcd efgh"'现在,你可以有一个你想转换成的字符串,'"abcd" "efgh"'你可以用它来做,sed 's/ /" "/'但这可能不是你想要的。

于 2012-08-03T16:36:10.703 回答