В моем файле mytxt
:
field1 field2
------ -------
this are numbers 12345
this letters abc def ghi
Скажем, я хочу сохранить первое поле в массиве:
i=0
while read line; do
field_one[$i]=$(echo $line | awk '{print $1}')
echo ${field_one[i]}
((i++))
done < mytxt
Это дало бы мне this
два раза в выводе.
Любые идеи того, как мог, я храню их в массиве и получаю вывод:
this are numbers
this letters
Я попытался изменить разделители, сжав пробелы и использование sed
, но я застреваю. Любая подсказка ценилась бы.
Моя заключительная цель состоит в том, чтобы сохранить оба поля в массиве.
Перемещение моего комментария, на основе этого источника, чтобы просто показать конкретный столбец на основанной на нескольких-пробелах таблице:
awk -F ' +' '{print $2}' mytxt.txt # Or with -F ' {2,}'
Я нашел особенно полезным найти дубликаты, с помощью чего-то как:
somelist... | sort | uniq -c | sort -rn | grep -vP "^ +1 " | awk -F ' +' '{print $3}'
Используя colrm для удаления столбцов из файла.
#!/bin/bash
shopt -s extglob
a=()
while read; do
a+=("${REPLY%%*( )}")
done < <(colrm 26 < text.txt)
printf %s\\n "${a[@]:2:3}"
(Bash встроенная версия):
#!/bin/bash
shopt -s extglob
a=()
while read; do
b="${REPLY::26}"; a+=("${b%%*( )}")
done < text.txt
printf %s\\n "${a[@]:2:3}"
Вы могли использовать встроенный удар mapfile
(иначе readarray
) с обратным вызовом, который использует расширение параметра для обрезки самой длинной запаздывающей подстроки, запускающейся с двух пробелов:
mapfile -c 1 -C 'f() { field_one[$1]="${2%% *}"; }; f' < mytxt
Напр. данный
$ cat mytxt
field1 field2
------ -------
this are numbers 12345
this letters abc def ghi
затем
$ mapfile -c 1 -C 'f() { field_one[$1]="${2%% *}"; }; f' < mytxt
$
$ printf '%s\n' "${field_one[@]}" | cat -A
field1$
------$
this are numbers$
this letters$
Этот ответ фокусируется на удалении двух строк заголовка от массива для соответствия требованиям к выходным характеристикам.
$ cat fieldone.txt
field1 field2
------ -------
this are numbers 12345
this letters abc def ghi
$ fieldone
this are numbers
this letters
Вот сценарий:
#!/bin/bash
# NAME: fieldone
# PATH: $HOME/askubuntu/
# DESC: Answer for: https://askubuntu.com/questions/1194620/
# how-would-you-separate-fields-with-multiple-spaces-and-store-them-in-an-array
# DATE: December 8, 2019.
i=0 # Current 0-based array index number
while read line; do # Read all lines from input file
((LineNo++)) # Current line number of input file
[[ $LineNo -eq 1 ]] && continue # "Field 1 Field 2" skip first line
if [[ $LineNo -eq 2 ]] ; then # Is this is line 2?
# Grab the second column position explained in:
# https://unix.stackexchange.com/questions/153339/
# how-to-find-a-position-of-a-character-using-grep
Len="$(grep -aob ' -' <<< "$line" | \grep -oE '[0-9]+')"
continue # Loop back for first field
fi
field_one[$i]="${line:0:$Len}" # Extract line position 0 for Len
echo "${field_one[i]}" # Display array index just added
((i++)) # Increment for next array element
done < fieldone.txt # Input filename fed into read loop
Надо надеяться, код и комментарии сам объяснительные. Если не прокомментируйте.
Сценарий все еще работает, если только одно пространство разделяет два столбца, тогда как некоторые другие ответы повредятся:
field1 field2
------ ------
this is letter abcdef
this is number 123456