1

これは本当に自明です。私はbashシェルで作業していて、シェルスクリプトを初めて使用します。使用に関する多くの情報を見つけましたが、これまでtrsed見つけたすべての例では、区切り文字と新しい行を削除しています。私は本当にその反対をしたいです。余白で分けられるようにしたいと思います。「abcdefgh」のような文字列があり、「abcd」「efgh」である必要があります(グループ化を示すために、すべて引用符なしで)。

これは私が作っているよりもはるかに簡単だと確信していますが、私は非常に混乱しています。

更新された質問:

配列に入れたPIDの列がありますが、配列の各要素の列には両方のpidがあります。

桁:

1234
5678

配列全体を印刷すると、すべての異なる列が追加されたため、すべての値が得られますが、配列の1つの要素を印刷すると、次のようになります。

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を分離する必要があります。たとえば、「3番目のpidは次のとおりです」という行は次のようになります。

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

他のソリューションはかなり良いです。カットをよく使います。ただし、常に空白で分割したい場合は、 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

外部コマンドを使用して文字列を単語に分割する必要はありません。setビルトインはまさにそれを行います:

string="abcd efgh"
set $string

# Now $1 is "abcd" and $2 is "efgh"
echo $1
echo $2
于 2012-08-03T20:36:28.853 に答える
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 に答える