Skrypt z parametrami - przeszukiwanie plików z zadanym kodem

Skrypt z parametrami - przeszukiwanie plików z zadanym kodem
GP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 34
0

Skrypt 2. Skrypt ma z katalogu SRC pobierać pliki o zadanych kodach i tworzyć z tych kodów podkatalogi.

Program ma sprawdzić czy w pliku, którego ścieżkę podajemy jako parametr jego wywołania, zawiera zdefiniowany na liście kod przesyłki. Jeśli zawiera kod AM01 plik ma z zostać przeniesiony do katalogu AM01 (jeśli katalogu nie ma, program ma go najpierw założyć), analogicznie jeśli AMA1 to do AMA1, a jeśli NL01 to do NL01.

Finalnie w katalogu SRC mają pozostać pliki z kodami innymi niż zdefiniowane na liście. W katalogu AM01 wszystkie pliki z kodem AM01, w katalogu AMA1 wszystkie pliki z kodem AMA1, a w katalogu NL01 wszystkie pliki z kodem NL01.

Może jakiś szkielet (podpowiedź?)
GB

Marius.Maximus
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2202
1

podpowiedz w jakiej technologi

S4
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1268
1

A czego nie umiesz zrobić ? Z hintów to Grep, Sed, a kopiowanie to już znajdziesz w dokumentacji.

ZD
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2310
0
S4t napisał(a):

... a kopiowanie to już znajdziesz w dokumentacji.

Obawiam się że chodzi o "zróbcie to za mnie"

GP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 34
0

Dobra coś takiego spłodziłem, ale poza jest katalog nie przenosi:(

Kopiuj
#!/bin/bash
if [ $# -ne 1 ]
then
        echo "Niepoprawna liczba argumentów. "
        exit 1
fi

LISTA="AM01 AMA1 NL01 "

if [ -d $1 ]
then

       echo "Jest katalog!"
       exit 1
        else
        echo "$1 nie jest katalogiem!"
        exit 1
fi


for i in *; do
  if [ -f "$i" ]; then
    z=`cat $i | grep -i $LISTA`
    if [ -n "$z" ]; then
      echo "Plik $i zawiera kod $z"
      if [ -d $z ]; do
        echo "Tworze katalog $z"
        mkdir $z
        mv $z ../
        else
         echo "Nie robie nic"
    fi
  fi
done

KS
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 708
1

Nie wiem czy zrozumiałem poprawnie co ma być zrobione i nawet nie sprawdziłem swojego kodu czy działa. Wrzucam na ślepo. Podejmuję ryzyko kompletnej kompromitacji.

Kopiuj

#!/bin/bash

chkfile="$1"
codelist="$2"

if test -e "$codelist"
then
	printf "Dupa blada\n" >&2
	exit
fi

if test -z "$chkfile"
then
	printf "Dupa blada\n" >&2
	exit
fi

while read -r code
do

	if grep -Fq "$code" "$chkfile"
	then

		if ! test -e "$code"
		then

			mkdir "$code"
		
		else

			if ! test -d "$code"
			then
				printf "blade dupsko\n" >&2
				exit
			fi

		fi

		cp -v "$chkfile" "$code"'/'

	fi


done < "$codelist"

GP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 34
0

Podaje parametry tak
./pliki3.sh SRC "AM01 AMA1 NL01"
wynik
./pliki3.sh: line 44: AM01 AMA1 NL01: No such file or directory

GP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 34
0

Popełniłem taki skrypt, ale nie przenosi mi po kodach do folderów o tych samych nazwach co KODy. Katalogi ma tworzyć poziom wyżej od SRC.

Kopiuj
#!/bin/bash


if [ $# -eq 0 ]; then
    echo 'brak parametru(ow) !'
    echo './plik.sh katalog1 '
    exit
fi

LISTA='AM01 AMA1 NL01'

while [ $# -gt 0 -a -d "$1" ]; do
   licznik=0
   for i in `find $1 -type f -printf "%p " 2>/dev/null`; do
   [ "`grep -l ${i##*/} $i 2>/dev/null`" ] && licznik=$[ $LISTA + 1 ]
   done

   echo katalog $1 ma $LISTA  kodow, z listy
   mkdir $licznik
   mv   $i ../
   shift
done

GP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 34
0
Kopiuj
#!/bin/bash


if [ $# -eq 0 ]; then
    echo 'brak parametru(ow) !'
    echo './plik.sh katalog1 '
    exit
fi

LISTA='AM01 AMA1 NL01'

   for i in $1; do
      for j in $LISTA; do
      [ "`grep -i ${LISTA} $1 2>/dev/null`" ]
   done
    echo -e "To jest wynik wykonania $LISTA i $i"
done

  if [[ -n $LISTA ]];
    then
       echo "katalog $1 ma $LISTA  kodow, z listy"
       mkdir $LISTA
       mv $LISTA ../
    else
       echo "Nie rob nic"
   fi

Mam teraz takie coś, ale nie tworzy podkatalogów i nie przenosi do nich plików z kodami.Help

MA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 134
0

Nie wiem czy dobrze rozumiem treść zadania.
Zrobiłbym coś takiego, żeby wykonać to zadanie (jak zwykle jedno-linijkowiec).

Kopiuj
for code in AM01 AMA1 NL01; do mkdir -p $code; mv $(grep -r $code ./src | awk -F '[:]' '{print $1}' | sort -u) $code;done

mkdir - tworzenie katalogu bez błędu, jeśli istnieje (-p)
grep - wyszukiwanie kodu we wszystkich plikach z katalogu src/
awk - wycięcie z użyciem dwukropka (path do pliku)
sort - usunięcie duplikatów (kod może się powtórzyć wielokrotnie w jednym pliku)
mv - przeniesienie do katalogu o nazwie kodu.

GP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 34
0

Jak zawsze super zoptymalizowany kod ja zrobiłem to tak:

Kopiuj
#!/bin/bash

set -x

KATDOMOWY=/root
KATZRODLOWY=$KATDOMOWY/SRC
SCIEZKA=$1
PLIK=${SCIEZKA##*/}

LISTA="AM01 AMA1 NL01"

cd $KATDOMOWY || exit

for KOD in $LISTA; do

  if grep -q $KOD $KATZRODLOWY/$PLIK; then
    [[ ! -d $KATDOMOWY/$KOD ]] && mkdir $KATDOMOWY/$KOD
    mv $KATZRODLOWY/$PLIK $KATDOMOWY/$KOD/
    break
  fi

done


GP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 34
0

Teraz mam coś podobnego trochę inne założenia i przeszukiwanie:

batch pobiera pliki i zapisuje w lokalnym katalogu instalacji

program ‘filtrujący’ działa w obrębie wskazanego katalogu

poszukuje plików z określonym statusem i przenosi je do określonego katalogu, pozostałe pliki do innego katalogu

definicje:

katalog źródłowy: TEST (c5) - root/pliki/sts_in

katalog docelowy: TEST (c5) - root/pliki/sts_to_process

katalog na ‘pozostałe’ pliki: TEST (c5) - root/sts_other

poszukiwany status 290 (jeżeli to możliwe to program powinien poszukiwać więcej niż jeden zdefiniowany status)

wzór pliku:

Kopiuj
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<documentStatuses xmlns='STATUSES-2.8' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
	<status>
		<interfaceType>MLTLEG</interfaceType>
		<objectType>MLTLEG</objectType>
		<objectNo>MJB220000056606</objectNo>
		<objectReference>MLL220000069167</objectReference>
		<statusCode>290</statusCode>
		<statusDate>20220901074900</statusDate>
		<statusTimezone>GMT Standard Time</statusTimezone>
		<propagationUp>1</propagationUp>
		<reference2>LIV0000717</reference2>
		<reference4>MJB220000056606</reference4>
	</status>
</documentStatuses>

założenia:

status znajduje się w tagu <statusCode>

należy ‘potrafić’ obsłużyć plik z pustym tagiem <statusCode> (przenieść do sts_other)

należy obsłużyć plik bez taga <statusCode> (przenieść do sts_other)
GP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 34
0

Nie wiem jak zbudować grep, aby szukał po między znacznikami <statusCode>290</statusCode> tylko kodu 290 lub pustego??
proszę o pomoc/

ZD
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2310
1

@gab-pro:

W pewnym momencie dodawania warunków szczegółowych ja bym olał bash & Co jako technologię, i walczył sekwencyjnym algorytmicznym językiem, np python.
Ale to z osobistego lenistwa :)

Deklaratywne ujęcia (a takie są argumenty do konkretnych programów) są super, zwięzłe, znane itd ... aż do momentu gdzie wyjdziemy z pewnej "strefy komfortu" do jakiego wizja była zamierzona. Później złożoność gwałtownie rośnie.
Podobnie w SQL bym pewnie nie robił modlitw, by porównać z poprzednim rekordem, tylko zrobił ten element na kliencie.

GP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 34
0

Mam zrobione tyle :

Kopiuj
#!/bin/bash

set -x

KATDOMOWY=/root
KATZRODLOWY=$KATDOMOWY/sts_in
KATDOCELOWY=$KATDOMOWY/sts_to_process
KATPOZOSTALE=$KATDOMOWY/sts_other

cd $KATDOMOWY || exit

for plik in ./*.xml; do

   kod=`grep -oE '<statusCode>290</statusCode>' ./*.xml`| echo ${kod:12:3}  <<Tu mam problem jak przegrepować 290 i <statusCode> czy w ogóle występuje?
   kod2=`grep -oE '<statusCode>' ./*.xml` | echo $kod2
  if [ $kod -eq 290 ] || [ $kod !='' ]; then
    mv $plik $KATDOMOWY/sts_to_process
    elif
     if [ $kod = '' ]; then
    mv $plik $KATDOMOWY/sts_other
    elif
     if [ $kod2 = '' ]; then
    mv $plik $KATDOMOWY/sts_other
   else
  fi

done
GP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 34
0

Tak wygląda mój skończony skrypt. Jak ktoś się pokusi o sprawdzenie działania to proszę o opinie i sugetie lub poprawki.

Kopiuj
#!/bin/bash

set -x

KATDOMOWY=/root
KATZRODLOWY=$KATDOMOWY/sts_in
KATDOCELOWY=$KATDOMOWY/sts_to_process
KATPOZOSTALE=$KATDOMOWY/sts_other
#PLIK=${SCIEZKA##*/}

cd $KATDOMOWY || exit
cd $KATDOMOWY/sts_in
for plik in ./*.xml; do

   kod=`grep -E "<statusCode>.*</statusCode>$" 01.xml | sed -e 's/<statusCode>\(.*\)<\/statusCode>/\1/'`
#   kod2=`grep -oE '<statusCode>' ./*.xml` done

  if [[ $kod -eq 290 ]] || [[ $kod != '' ]]; then
    mv $plik $KATDOMOWY/sts_to_process
    echo Przenosze do sts_to_process.
    else
    mv $plik $KATDOMOWY/sts_other
    echo Przenosze do sts_other.
fi

done
hauleth
  • Rejestracja: dni
  • Ostatnio: dni
1

Zacznijmy od sprawdzenia ShellCheck:

Kopiuj
Line 6:
KATZRODLOWY=$KATDOMOWY/sts_in
^-- SC2034 (warning): KATZRODLOWY appears unused. Verify use (or export if used externally).
 
Line 7:
KATDOCELOWY=$KATDOMOWY/sts_to_process
^-- SC2034 (warning): KATDOCELOWY appears unused. Verify use (or export if used externally).
 
Line 8:
KATPOZOSTALE=$KATDOMOWY/sts_other
^-- SC2034 (warning): KATPOZOSTALE appears unused. Verify use (or export if used externally).
 
Line 12:
cd $KATDOMOWY/sts_in
^-- SC2164 (warning): Use 'cd ... || exit' or 'cd ... || return' in case cd fails.

Did you mean: (apply this, apply all SC2164)
cd $KATDOMOWY/sts_in || exit
 
Line 15:
   kod=`grep -E "<statusCode>.*</statusCode>$" 01.xml | sed -e 's/<statusCode>\(.*\)<\/statusCode>/\1/'`
       ^-- SC2006 (style): Use $(...) notation instead of legacy backticks `...`.

Did you mean: (apply this, apply all SC2006)
   kod=$(grep -E "<statusCode>.*</statusCode>$" 01.xml | sed -e 's/<statusCode>\(.*\)<\/statusCode>/\1/')
 
Line 19:
    mv $plik $KATDOMOWY/sts_to_process
       ^-- SC2086 (info): Double quote to prevent globbing and word splitting.

Did you mean: (apply this, apply all SC2086)
    mv "$plik" $KATDOMOWY/sts_to_process
 
Line 20:
    echo Przenosze do sts_to_process.
                   ^-- SC1010 (warning): Use semicolon or linefeed before 'do' (or quote to make it literal).
 
Line 22:
    mv $plik $KATDOMOWY/sts_other
       ^-- SC2086 (info): Double quote to prevent globbing and word splitting.

Did you mean: (apply this, apply all SC2086)
    mv "$plik" $KATDOMOWY/sts_other
 
Line 23:
    echo Przenosze do sts_other.
                   ^-- SC1010 (warning): Use semicolon or linefeed before 'do' (or quote to make it literal).

Więc trochę rzeczy jest takich co można poprawić.

GP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 34
0

A może jakieś konkrety? Może ktoś ma pomysł na użycie xmllint z pętlą while?
xmllint --xpath "290//statusCode" 01.xml

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.