2013-12-15 4 views
0

Ниже мой файл input.txt, разделенный запятой, я хочу прочитать столбцы и записать строки в output.txt, если в одном столбце есть пробел.Удалить строки, содержащие пробел в unix

Содержание input.txt:

1,Hello,world 
2,worl d,hell o 
3,h e l l o, world 
4,Hello_Hello,[email protected]# 
5,Hello,W orld 

Содержание output.txt:

1,Hello,world 
4,Hello_Hello,[email protected]# 

is't можно достичь с помощью awk? Пожалуйста помоги!

+0

Зачем использовать 'awk', когда' grep -v' будет работать отлично? – SuperSaiyan

+3

'is't' - самая странная орфографическая ошибка, которую я видел в этом году. Клянусь. –

+2

Обновление вопроса с дополнительным требованием, изменяющим игру, после того, как вы получили несколько существенных ответов, не является хорошей формой. У меня возникнет соблазн предложить вернуться к редактированию, принять ответ и задать новый вопрос. – tripleee

ответ

10

Простой способ отфильтровать строки с пробелами использует перевернутый соответствие с grep:

grep -v ' ' input.txt 

Если необходимо использовать awk:

awk '!/ /' input.txt 

Или perl:

perl -ne '//|| print' input.txt 

Или чисто bash:

while read line; do [[ $line == *' '* ]] || echo $line; done < input.txt 
# or 
while read line; do [[ $line =~ ' ' ]] || echo $line; done < input.txt 

UPDATE

Чтобы проверить, если, скажем, поле 2 содержит пространство, вы могли бы использовать awk так:

awk -F, '$2 !~//' input.txt 

Чтобы проверить, если, скажем, поле 2 ИЛИ поле 3 содержит пробел:

awk -F, '!($2 ~// || $3 ~//)' input.txt 

Для вашего последующего вопроса в комментариях

Чтобы сделать то же самое с помощью sed, я знаю только эти неудобные решения:

# remove lines if 2nd field contains space 
sed -e '/^[^,]*,[^,]* /d' input.txt 
# remove lines if 2nd or 3rd field contains space 
sed -e '/^[^,]*,[^,]* /d' -e '/^[^,]*,[^,]*,[^,]* /d' input.txt 

Для вашего 2-й последующего вопроса в комментариях

Для игнорирования ведущих пространств в 2-м или 3-м полях:

awk -F', *' '!($2 ~// || $3 ~//)' input.txt 
# or perhaps what you really want is this: 
awk -F', *' -v OFS=, '!($2 ~// || $3 ~//) { print $1, $2, $3 }' input.txt 
+2

Вам не нужно {print}, поскольку это действие по умолчанию для awk. – stark

+0

@stark вы абсолютно правы! – janos

+0

Спасибо @Jason за 'awk'. как изменить 'awk', чтобы проверить только одно или два поля? – Marjer

5

Это также можно легко сделать с

sed '/ /d' input.txt 
+0

Спасибо, но моя проблема в том, что я хочу проверить конкретный столбец. Я пропустил добавить это в вопрос. – Marjer

3

попробовать этот Однострочник

awk 'NF==1' file 

, как @jwpat7 отметил, что не даст правильный вывод, если линия имеет только ведущие space, то эта строка, с регулярным выражением, должна делать, но она уже отправлена ​​в ответ janos.

awk '!/ /' file 

или

awk -F' *' 'NF==1' 
+1

Я бы добавил +1, если бы это сработало ... но это терпит неудачу, когда дисквалифицирующие пробелы находятся впереди линии. –

+2

Довольно аккуратный, но довольно неясный. Awk разбивается на пробелы и устанавливает 'NF' количество полей; если он один, не было пробелов для разделения. – tripleee

+1

@ jwpat7 Вы, конечно, правы; но примеры OP указывают на то, что это не проблема. – tripleee

1

Pure Баш для удовольствия ...

#!/bin/bash 

while read line 
do 
    if [[ ! $line =~ " " ]] 
    then 
     echo $line 
    fi 
done < input.txt 
0
columnWithSpace=2 
ColumnBef=$((${columnWithSpace} - 1)) 

sed '/\([^,]*,\)\{${ColumnBef\}[^ ,]* [^,]*,/ d' 

, если вы знаете колонку непосредственно (на примере 3):

sed '/\([^,]*,\)\{2}[^ ,]* [^,]*,/ d' 
0

Если вы можете доверять тому, что вход всегда имеет не более трех полей, просто найдите место где-нибудь после запятой.

grep ',.* ' input.txt 

Если может быть (или обычно) несколько полей, вы можете осуществить это с grep -E и подходящим ERE, но вы быстро приближается к точке, в которой эквивалентное решение Awk будет более удобным для чтения и ремонтопригодны ,

Смежные вопросы