Только покажите строки, которые находятся во всех текстовых файлах, по крайней мере, однажды

Ну, для дальнейшего использования по крайней мере:

synclient touchpadoff=1

Отключает сенсорную панель, touchpadoff=0 включает ее снова.

Я поместил это в файл сценария, добавил он к материалу Автоматического запуска, и когда мой рабочий стол запускает, несколько секунд спустя, когда файлы автоматического запуска выполняются, мышь сенсорной панели ВЫКЛЮЧЕНА.

Это удобно, так как я могу запустить другой скрипт 'разрешать-сенсорная-панель', которая снова включает его (у меня есть 'сенсорная панель переключателя' также!), который позволяет мне использовать сенсорную панель в очень маловероятном событии, я потерял свою мышь. (Я ненавижу сенсорную панель meece!)

помещение в черный список psmouse, конечно, работает, но удаляет возможность использования его в повышении легко.

Я на самом деле добавил горячую клавишу (Победа-M) для переключения состояния сенсорной панели, поэтому когда я активен, если мне нужен он, это - всего два ключа далеко. (редкий, но действительно происходит!)

4
05.09.2013, 21:49
6 ответов

Как насчет

cat *.txt | sort | uniq -c | egrep "^ +$(ls -1 *.txt | wc -l) "

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

cat *.txt | sort | uniq -c | egrep "^ +$(ls -1 *.txt | wc -l) " | sed -re 's/^ +[0-9]+ //'

Согласно комментарию @Stephane вышеупомянутого не будет работать, если строка появится многократно в единственном файле. Здесь я сортирую и uniq каждый файл сначала, чтобы избежать что:

for f in *.txt; do sort -u $f > $f.uniqd; done
cat *.uniqd | sort | uniq -c | egrep "^ +$(ls -1 *.uniqd | wc -l) " | sed -re 's/^ +[0-9]+ //'

Хотя теперь это больше не острота.:)

4
27.01.2020, 20:46
  • 1
    *.txt | uniq-c | egrep "^ + $ (/bin/ls-1 *.txt | туалет-l)" –  gasko peter 05.09.2013, 21:48
  • 2
    Это не работает на строки, которые появляются несколько раз в файле. –  Stéphane Chazelas 06.09.2013, 00:14
  • 3
    sort -u ярлык для sort | uniq. Кроме того, cat * | sort может быть сокращен к sort *. –  200_success 06.09.2013, 18:04
awk 'FNR == 1 { FILENUM++ }
     SEEN[$0] == FILENUM - 1 { SEEN[$0] = FILENUM }
     END { for (s in SEEN) if (FILENUM == SEEN[s]) print s }' *.txt

Объяснение

При чтении первой строки каждого файла, инкремента FILENUM, так, чтобы при чтении n th файл, FILENUM n.

При чтении каждой строки считайте количество файлов, в которых та строка была замечена (но только необходимо потрудиться делать это, если строка была замечена в каждом предыдущем файле).

Когда там больше не вводится, чтобы считать, распечатать все строки, которые были замечены во всех файлах.

Внимание: Как с несколькими из решений, отправленных здесь, у этого также есть слабость. Согласно вопросу, если какой-либо из входных файлов пуст, там, как предполагается, не вывод вообще. Однако, так как awk является ориентированным на строку инструментом, он игнорирует пустые файлы. Таким образом, FNR == 1 { FILENUM++ } сбои для постепенного увеличения FILENUM для пустых файлов.

С GNU awk, возможно исправить эту ошибку с помощью ARGIND встроенная переменная.

gawk 'SEEN[$0] == ARGIND - 1 { SEEN[$0] = ARGIND }
      END { for (s in SEEN) if (ARGIND == SEEN[s]) print s }' *.txt
4
27.01.2020, 20:46

Используя GNU awk

awk '{
      x[$0][FILENAME]
     }
     END{
      num_files=ARGC-1;
      for (b in x)
       if (length(x[b]) == num_files) 
        print b
     }' a.txt b.txt c.txt
3
27.01.2020, 20:46
  • 1
    , как использовать это?:\:D –  gasko peter 05.09.2013, 21:41
  • 2
    @gaskopeter, предполагая, что у Вас есть 3 файла abc.txt, b.txt, c.txt, вызовите команду точно как выше –  iruvar 05.09.2013, 21:42
  • 3
    , который она дает синтаксической ошибке в 'x [0$] [ИМЯ ФАЙЛА]' - использование Ubuntu 12.04 –  gasko peter 05.09.2013, 21:44
  • 4
    @gaskopeter, казалось бы, что Вы работаете на более старой версии awk –  iruvar 05.09.2013, 21:54
  • 5
    @1_CR Ubuntu/Debian использование mawk по умолчанию. Возможно, Вы используете a gawk функция? –  jordanm 05.09.2013, 22:51

Вы могли сделать:

export LC_ALL=C
sort -u a.txt |
  comm -12 - <(sort -u b.txt) |
  comm -12 - <(sort -u c.txt) |
  comm -12 - <(sort -u d.txt)

Который был бы относительно эффективен, но это не легко расширить на произвольное число файлов.

2
27.01.2020, 20:46

Мне нравится более легкое использование решения join:

join <(sort a.txt) <(sort b.txt)

Это действительно работает над Вашими двумя входными файлами, но не может вести себя, как Вы ожидаете на строках, содержащих пробелы, это также произведет дублирующиеся строки многократно.

Исправить второй выпуск, просто

join <(sort a.txt) <(sort b.txt) | uniq

Первое немного более сложно, но я обманул немного с -t флаг, для использования непоявления charachter в качестве разделителя полей:

$ cat a.txt 
This test
foo bar
does work
$ cat b.txt 
This is a test
foo does not work
does work
$ join <(sort a.txt) <(sort b.txt) | uniq
does work work
foo bar does not work
This test is a test
$ join -t : <(sort a.txt) <(sort b.txt) | uniq
does work
1
27.01.2020, 20:46
  • 1
    Это не будет работать на три файла или больше, затем необходимо было бы находиться к, цикл, как описано @slm –  Bernhard 06.09.2013, 09:55

Для 2 файлов

Это не более сложно, чем использование grepспособность использовать список слов. Например:

$ grep -f b.txt a.txt 

Пример

# a.txt
$ cat a.txt 
a
abc defg
de
bcd
xyz bcd
c

# b.txt
$ cat b.txt 
d
e bcd
a
f
bcd

# common lines to a.txt & b.txt
$ grep -Fxf b.txt a.txt
a
bcd

Примечание: В зависимости от данных Вы, возможно, должны добавить a | sort -u после grep если какие-либо строки дублированы в файлах!

Подробнее

-F, --fixed-strings
     Interpret PATTERN as a list of fixed strings, separated by newlines, 
     any of which is to be matched.  (-F is specified by POSIX.)

-x, --line-regexp
     Select only those matches that exactly match the whole line.  
     (-x is specified by POSIX.)

-f FILE, --file=FILE
     Obtain patterns from FILE, one per line.  The empty file contains 
     zero patterns, and therefore matches nothing.  (-f is specified by 
     POSIX.)

Для 3 или больше

Можно использовать то, что при сравнении какого-либо файла с другими, что, что когда-либо распространено через всех них по сравнению с этим файлом, затем все файлы должны совместно использовать эту общую строку. Снова использование grep -f как выше, но на этот раз мы должны будем циклично выполниться через файлы с помощью a for цикл.

$ mf=""; for i in *.txt; do [ -z "$mf" ] && mf=$i && continue; grep -Fxf $mf $i;done | sort -u

Если мы добавляем некоторые дополнительные файлы в соединение:

# c.txt
$ cat c.txt 
a
z
d bcd
e
q
bcd

# d.txt
$ cat d.txt 
a
z
e
z bcd
bcd

Выполнение нашего кода производит это:

$ mf=""; for i in *.txt;do [ -z "$mf" ] && mf=$i && continue; grep -Fxf $mf $i;done | sort -u
a
bcd
1
27.01.2020, 20:46
  • 1
    , Чтобы заставить это работать больше чем с 2 входными файлами, Вы оказываетесь перед необходимостью обращаться для обработки замены –  iruvar 05.09.2013, 22:01
  • 2
    @1_CR - извините я не следую за Вами с точки зрения комментария замены процесса. Я понимаю то, что Вы говорите> 2 .txt файла. Этот подход мог быть изменен так, чтобы Вы выполнили его против 2 + файлы все же. –  slm♦ 05.09.2013, 22:05
  • 3
    я имел в виду grep -f <(grep -f a.txt b.txt) c.txt, но я вижу, что Вы, кажется, решили его по-другому –  iruvar 05.09.2013, 22:59
  • 4
    @1_CR - спасибо, имеет смысл. Я хотел что-то, что было более динамично, если были *.txt файлы. –  slm♦ 05.09.2013, 23:10
  • 5
    @200_success - благодарит указать на это. Должен быть зафиксирован теперь. –  slm♦ 06.09.2013, 18:51

Теги

Похожие вопросы