Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Регулярка для цепного вытаскивания #include <?.h>

Добрый вечер
Преподаватель дал задание написать скрипт для цепного поиска #include в заданном файле (то есть в main.cpp допустим считывает #include <3.h>, потом открывает 3.h и считывает инклюды из него) используя grep, sed и регулярку, которую он нам показал

Сам скрипт написан, всё работает:

Сама получившаяся строка поиска:
Bash
1
 CUR_LIST_INCLUDE=`grep -i -E ^*#include $CUR_FILE | sed 's@.*"\(.*\)"@\1@' | col` # Вытаскиваем все "#include" в файле
Можете помочь расшифровать 's@.*"\(.*\)"@\1@' | col`?
Ответ: Почитайте про . Зачем Ваш преподаватель его встаил — представить даже не могу. Или у Вас такие древние терминалы, что они управляющие последовательности не понимают?
s@.*"\(.*\)"@\1@' заменяет текст с начала строки с текстом внутри кавычек «"» на текст внутри кавычек, т.е. строку вида
#include some text "text in quotes"
в
text in quotes
Ну и добейте препода
Bash
1
CUR_LIST_INCLUDE=$(sed -n '/#include/s@.*"\(.*\)"@\1@ip' $CUR_FILE | col)
Тем более что ^*#include некорректный регэксп
Вопрос: Split: выделение определённой части

Дано: два компьютера, .vdi размером 18Gb на одном из них, забитом почти под 100%, USB флешка на 16Gb
Надо: перенести по-быстрее из одного винта на другой.

Для решения я использую команду split
Код Bash
1
split -b 8G -d VirtualBox\ VMs/MS7OS/MS7OS.vdi /media/KINGSTON/MS7OS.vdi.part
которая создаёт части исходного файла MS7OS.vdi сразу на флешке: /media/KINGSTON/MS7OS.vdi.part[1-3]. Тем временем мне подумалось, что когда флешка будет переполнена, программа просто отключится, бросив какую-то ошибку, и я смогу перенести части на новый винт.

Тем не менее, я не знаю, как при втором заходе сказать split, что нужно первые два куска игнорировать.
Вариант освободить место, сопоставимое с копией .vdi, для создания локально всех частей и перенести последнюю, а остальные удалить мне не нравится из-за своей костыльности и большого числа лишних (откровенно ненужных) телодвижений. Я искренне верю, что можно решить адекватно эту задачу более естественным способом.

Что посоветуете?
Ответ: Mysterious Light, Поняли правильно. У yekka правильный способ, у меня более простой.
Вопрос: Вывести попеременно введенную строку и по 2 строки из файла

Здравствуйте, уважаемые форумчане! Доброго вам времени суток! =)

Возник у меня вопрос по shell-у. Пишу shell-процедуру, которая:
1) вводит символьную строку, содержащую два целых числа m и n, разделенных пробелами.
2) читает содержимое файла, передаваемого в качестве первого параметра.
3) выводит на экран каждые m секунд попеременно n строк из файла и пустую строчку.

С помощью данного форума написал почти все =) Получилось так:

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# Program, Variant 37
 
# Проверим количество аргументов, переданных в процедуру.
# --------------------------------
 
# Если количество аргументов, переданных в процедуру, не равно 1...
if [ $# -ne 1 ]; then
 
# Выведем ошибку на экран.
echo 'Error count of arguments! Try again!'
 
# Выход с кодом ошибки.
exit
 
fi
# -------------------------------
 
# Ввод параметров в символьной строчке.
# -----------------------------
 
# Вывод приглашения без перевода строчки.
echo -n "Enter numbers M and N:  "
 
# Ввод строчки в переменную s
read s
 
# Составляем массив из строки. Пробелы заменяются на пробелы.
# Элементы массива разделяются по пробелу.
nums=(${s// / })
 
# Для отладки - вывести элементы массива.
echo ${nums[0]}, ${nums[1]}
 
# -----------------------------
 
# Основной цикл программки.
 
while true; do
 
flines=$(head -${nums[1]} $1)
 
echo $flines
 
sleep ${nums[0]}
 
echo
 
done
 
echo $0
И возник вопрос- как мне вывести не просто первые N строчек из файла, а постоянно каждые следующие N? Ну например, пусть в файле есть строчки:

-1
-2
-3
-4
-5
-6
-7
-8
-9
-10
И пусть N = 2.
Мне надо, чтобы из файла каждые три секунды выводилось эти строчки по две:

-1
-2
...
-3
-4
...
Не получается =)) Помогите, пожалуйста =))

Заранее всем спасибо!

P.S.
И , если будет время, объясните, пожалуйста, как работает строчка:

Bash
1
nums=(${s// / })
Ответ: вот мой код,который верно работает
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
if [ -e $1 ]                            #проверка существования файла
then                                    #если файл существует
  echo "Введите строку"                 #приглашение к вводу
  read str                              #читаем строку
  file=$1                               #открываем файл
  if [ $str -gt 0 ] || [ $str -lt 1 ]   #проверка, являеся ли строка числом
        #если не является, то вернёт ошибку и вызовет блок else, если
        #если являеься, то неравенство всегла вернёт 1 ( < 1 or > 0 )
  then                                  #строка является числом
  while true                            #бесконечный цикл считывания из файлоа
  do
    while read line                     #вложенный конечный цикл, считывание
    do                                  #происходит, пока это возможно
      echo $line                        #вывели строку считанную в while read
      read line                         #считали следующую строку
      echo $line                        #вывели её
      echo $str                         #вывели строку, введённую с клавиатуры
      sleep 6                           #задержка 6 секунд
    done < $file                        #цикл считывает строки из файла
     sleep 6                           #задержка 6 секунд
    done < $file                        #цикл считывает строки из файла
  done                                  #конец основного бесконечно цикла
  else                                  #случай некорректной строки
    echo "Некорректная строка"          #выводим сообщение
  fi
else                                    #случай некорректного файла
  echo "Файл не существует"
fi
Вопрос: Копирование указанных строк

Привет, сообщество.

В общем, проблема с созданием скрипта, в этой теме еще новичок, поэтому ничего не получается в принципе.

Задача следующая:
Каждую n-ю строку одного заданного файла дописать в качестве содержимого другого заданного файла.
Примечание. Оба имени файлов, а также число n должны вводиться с командной строки в качестве параметров скрипта.

Нужно sed + shell скрипт, либо что-то типа такого (извините, если что-то смешное ляпнул).

Сейчас только что могу, так это удалить строки, в заданном интервале:
Bash
1
sed  $1 >f1  -e  {“  $2,$3 d  “}  cp  f1  $1
Здесь $1 - имя файла, $2 и $3 - номера первой и последней строки. А вот как удалить n-ую строку, не пойму.

А как решить исходную, не знаю. Буду рад за любую помощь.
Спасибо!

Добавлено через 10 минут
Обновление:
Вот такой командой удаляю все четные строки и результат сохраняю в B.txt:
Bash
1
sed '0~2d' A.txt > B.txt
Экспериментируя, примерно понял что в '0~2d' означает, что удаляются строки, номера которых делятся на 2.
Таким образом, получается что d - удаление. Логично, есть что-то типа append в другой файл в этом же формате)
Есть ли ?)

Добавлено через 6 минут
Еще вопрос, можно ли оставить только указанные строки и записать их в нужный файл?
То есть пример выше удаляет указанные строки, а нужно наоборот, оставить эти строки.

Добавлено через 21 минуту
Получать только нужные строки получилось вот так:
Bash
1
sed '0~3d' A.txt > temp && diff -E -b -B -w A.txt temp | fgrep "<" > tdiff && rm temp
Только впереди символ '<', если бы от него избавиться и полученный файл дописывать в файл B.txt было бы уже отлично

Хороший у меня монолог получается
Ответ:
Сообщение от Marinero
Bash
1
sed -n '2~2p' A.txt > B.txt
Вот эта часть помогла, спасибо!
Теперь новая проблема. Со второй частью задания, где мне нужно чтобы параметры шли через командную строку.
Засунул код в файл script.sh:
Bash
1
sed -n '0~$3' $1 > $2
$1 - название исходного файла, $2 - название файла куда нужно сохранить строки, ну и $3 - n по условию, т.е. какие номера строк надо выписать.
Запускаю так:
Bash
1
sh script.sh A.txt B.txt 3
Естественно, ругается на $3. Попробовал взять в кавычки внутри - не проканало. Как же быть, чтобы этот параметр изменялся?

Добавлено через 2 часа 44 минуты
Вопрос закрыт.

Просто кавычки другие снаружи оказывается нужны были.

Bash
1
sed -n "0~$3p" $1 > $2
Вопрос: Удаление полностью идентичных (дублирующихся строк) при использовании sed

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

Кликните здесь для просмотра всего текста
\tworkgroup = WORKGROUP
\tworkgroup = WORKGROUP
\tworkgroup = WORKGROUP

workgroup = WORKGROUP
workgroup = WORKGROUP33
workgroup = WORKGROUP22
workgroup= WORKGROUP
workgroup=WORKGROUP22

Интересное предположение

\tsamba = SAMBA
\tsamba = SAMBA
work = ws-1



Написал небольшую функцию по удалению похожих строк в конфигурационном файле, но полностью идентичные строки не получается удалить

Кликните здесь для просмотра всего текста
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/usr/bin/env bash
 
# удаление повторяющихся строк
 
file=./smb2.conf
 
function delete_duplicate_str(){
dub=$(sort $file | uniq -d)
 
 if  [[ -n "${dub}"  ]] 
 then
 echo
 echo -e  "Найдены идентичные строки :\n ${dub}"
 echo
local et=$1
local et2=$2
#reg=$(grep -Px "\t${et} = .*" $file)
duplicate_1=$(grep -Px "^\t${et}\s=\s${et2}$" $file)
duplicate_2=$(grep -Px "^\t${et}\s=.*$" $file)
 
      if [[ -n "${duplicate_1}" ]]
    then
        echo
        echo  -e "Найдено полностью идентичных совпадений опций по умолчанию:\n ${duplicate_1} "
        echo
        echo -e "Удалим только похожие совпадения "
       sed -i -r "/${et}\s*=/{/^\t${et}\s= \b${et2}\b/! d}" $file
   else
       echo "совпадений не найдено"
      #sed -i -r "/${et}\s*=/{/^\tw.* = \b${et2}\b/! d}" $file
      fi
 else
     echo "совпадений нет"
 fi 
 
# -n -проверяет, что строка не пустая
}
 
 
 delete_duplicate_str "workgroup" "WORKGROUP" 
 
 # delete_duplicate_str "samba" "SAMBA"
 
 
 # local et=$1 
 # $1 - 1-й аргумент - это эталонное слово для поиска нужной опции
 # local et=$2 
 # $2 - 2-й аргумент - это эталонное слово для поиска значения
 # по умолчанию соответствующей опции
 # duplicate_1 - данная переменная содержит вычисляемое выражение - $(выражение)
 #  это выражение позволяет определить есть ли в данном файле опций со значениями по умолчанию
 # 
  # grep -Px - поиск слов с применением регулярных выражений
  # -P или --perl-regexp  - этот ключ, означает использование  ШАБЛОНа - регулярного выражения языка Perl
  # -x  -  поиск точного вхождения слова
  # ^ - якорь в регулярных выражениях, означает "начало строки"
  # \s - один пробельный символ
  # $  - якорь в регулярных выражениях, означает "конец строки"



Пробовал так

Bash
1
 delete_duplicate_str "workgroup" "WORKGROUP" < sed  "2,$d
или так

Bash
1
 delete_duplicate_str "workgroup" "WORKGROUP" | sed  "2,$d
Не работает.
Может ли утилита sed справиться с этой задачей ?
Ответ: Выкладываю честно стыренный где-то ранее (где не помню) мною код для удаления одинаковых строк, идущих не подряд.
Я не говорю что он элегантен или короток. Просто он у меня был

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/bin/bash
 
# определяет повторяющиеся строки в файле
# оставляет в файле только одну из повторяющихся строк
 
error()
{
    echo "error: $1" 1>&2
}
 
remdups()
{
    local fname=$1 tmpname
    
    tmpname=${fname}_
    
    if sort -u "$fname" > "$tmpname"; then
        mv -f "$tmpname" "$fname"
    else
        [ -f "$tmpname" ] && rm -f "$tmpname"
    fi
}
 
selfile()
{
    echo "Select file"
    n=0
    while true; do
        read -p "Enter: " fname
        ((n++))
        if [ -f "$fname" ]; then
            echo -n "Processing $fname... "
            remdups "$fname" && echo "ok"
            break
        elif [ $n -lt 3 ]; then
            error "no such file"
        else
            error "all names are wrong"
            break
        fi
    done
}
 
readfile()
{
    echo "Read file"
    n=0
    while true; do
        read -p "Enter: " fname
        ((n++))
        if [ -f "$fname" ]; then
            cat "$fname"
            break
        elif [ $n -lt 3 ]; then
            error "no such file"
        else
            error "all names are wrong"
            break
        fi
    done
}
 
cont=1
while [ $cont -eq 1 ]; do
    select ch in "Select" "List" "Read" "Exit"; do
        case "$ch" in
          "Select") selfile;;
          "List") ls;;
          "Read") readfile;;
          "Exit") cont=0; break;;
        esac 
    done
done
 
exit 0
Вопрос: Скрипт на замену строки в файле

создаю файл обзываю script
пишу:
Код Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# параметр file – имя редактируемого файла
# параметр n1 – номер первой заменяемой строки
# параметр n2 – номер последней заменяемой строки
 
echo -n "Введите имя файла:"
read file
echo -n "Введите номер первой заменяемой строки:"
read n1
echo -n "Введите номер последней заменяемой строки:"
read n2
 
sed $ file >f1 -e {“
$ n1,$ n2 d
“}
cp f1 $1
сохраняю - запускаю - ничего не происходит
подскажите где ошибся?
Ответ: в задаче стоит заменить непрерывную строку символов на строку с клавиатуры , может я вабще не то наваял?

Добавлено через 6 часов 1 минуту
во как
Код Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# параметр file  – имя редактируемого файла
 
# параметр text1 – Текст, который нужно заменить
 
# параметр text2 – Заменяемый текст с клавиатуры
 
 
 
echo -n "Введите имя файла:"
 
read namefile
 
echo -n "Введите непрерывную последовательность символов, которую нужно заменить:"
 
read text1
 
echo -n "Введите текст для замены:"
 
read text2
 
 
sed -e  "s/$text1/$text2/" $namefile
Вопрос: Sed замена строки по номеру

Здравствуйте! долго искал, но ответа не нашел, помогите пожалуйста.

есть файл config.php, в нем нужно третью строку заменить на другую.

пример
Код PHP
1
2
3
4
5
6
7
<?php
$config['ver'] = '3.0';
$config['domain'] = 'domain.com';
$config['client'] = 'client.com';
$config['debug'] = FALSE;
$config['charset'] = 'utf-8';
?>
нужно вместо третьей строки вставить $config['domain'] = 'domain2.com';
либо просто изменить значение в кавычках domain.com
посоветуйте как быть
Ответ:
Сообщение от Marinero
Velesthau, все варианты исходных данных не предусмотришь
Все предусматривать не нужно. Каждый предусматривает столько, сколько считает нужным.
Сообщение от Marinero
всё равно это делается не так.
Это делается как угодно Когда строки в файлах небольшие, предпочитаю заменять их полностью, чтобы строка была в точности такой, какой я ее хочу видеть. Так что, для меня твой вариант - это "не так".
Вопрос: Рекурсивно найти файлы в заданном каталоге содержащие заданную строку

Написать скрипт для поиска заданной пользователем строки во всех файлах заданного каталога и всех его подкаталогов (строка и имя каталога задаются пользователем в качестве первого и второго аргумента командной строки). На консоль выводятся полный путь и имена файлов, в содержимом которых присутствует заданная строка, и их размер. Если к какому либо каталогу нет доступа, необходимо вывести соответсвующее сообщение и продолжить выполнение.
Ответ:
Bash
1
readlink -m $(grep -lrF 'строка' /dir_name)
Вопрос: Настроить vim (новые строки со знаком комментария)

Если курсор находится на строчке начинающейся со знака коментария # // или /*
при вставке новой строки то есть при нажатии "o" или "O" или переводе на новую строку,
знак коментария на автомате ставится в новой строке. Подскажите как правильно подправить
.vimrc что бы отключить эту фичу.
Ответ: Marinero, Разбиралась по ссылке,
если набрать в командной строке vim:
Bash
1
: setlocal comments-=://
То коментарии // уже не появляются в новой строке в файлах Си.
Что бы увековечить результат в конце .vimrc прописала:
Bash
1
au FileType c setlocal comments-=://
Мне этого достаточно. Спасибо.
Вопрос: Оставить в каждой строке не более 2-х слов

1) В созданном текстовом файле оставить в каждой строке не более 2-х слов. Остаток перенести в следующую строку. Если вторая строка в паре оказывается пустой - печатать в ней символ '='.
Ответ:
Bash
1
sed 's/\(\S\+\s\S\+\)\s/\1\n/g' text.file
Сообщение от Seo-SSSR
вторая строка в паре оказывается пустой
— что это значит не понял.